home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / utils1 / fdate84a.arj / FDATE.DOC < prev    next >
Text File  |  1994-03-25  |  125KB  |  3,209 lines

  1. FDATE                     Version 8.4a               March 20, 1994
  2. ======================================================================
  3. AUTHOR:     Stephen Ferg             
  4.             5113 N. 8th Road 
  5.             Arlington, VA 22205-1201
  6.             USA
  7.  
  8.             telephone (voice, not FAX): (703) 525-2241
  9.             CompuServe ID             : 73377,1157
  10.             Internet                  : 73377.1157@compuserve.com
  11.  
  12. =======================================================================
  13.  
  14.  
  15.  
  16.                              Table of Contents
  17.  
  18. Page numbers in the WordPerfect version of FDATE.DOC (which is not
  19. distributed with FDATE) are lost in the conversion to ASCII format. 
  20. Nevertheless, these page numbers give you a rough idea of the relative
  21. locations of the different sections.
  22.  
  23.   WHAT IS FDATE?. . . . . . . . . . . . . . . . . . . . . . . . . . . .   4
  24.      OTHER UTILITIES NAMED "FDATE". . . . . . . . . . . . . . . . . . .   5
  25.      OVERVIEW OF PARAMETERS . . . . . . . . . . . . . . . . . . . . . .   6
  26.      OVERVIEW OF FUNCTIONS. . . . . . . . . . . . . . . . . . . . . . .   8
  27.   FUNCTIONS: DETAILED DESCRIPTIONS. . . . . . . . . . . . . . . . . . .  10
  28.      DATE FORMATTING FUNCTIONS. . . . . . . . . . . . . . . . . . . . .  10
  29.      DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . . . . . .  11
  30.      MONTH DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . . .  12
  31.      WEEKDAY DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . .  13
  32.      DATE/TIME COMPARISON FUNCTIONS . . . . . . . . . . . . . . . . . .  14
  33.      COMPARE-FUNCTION ERRORLEVELS . . . . . . . . . . . . . . . . . . .  14
  34.      NUMERIC ARITHMETIC FUNCTIONS . . . . . . . . . . . . . . . . . . .  15
  35.      DATE VALIDATION FUNCTION . . . . . . . . . . . . . . . . . . . . .  17
  36.   STRING FUNCTIONS. . . . . . . . . . . . . . . . . . . . . . . . . . .  18
  37.      GET and GETU (GET USER INPUT) FUNCTION . . . . . . . . . . . . . .  18
  38.      GETK (GET KEYPRESS) FUNCTION . . . . . . . . . . . . . . . . . . .  19
  39.        Specifying the Keymask . . . . . . . . . . . . . . . . . . . . .  19
  40.        GetK Results also in ERRORLEVEL. . . . . . . . . . . . . . . . .  20
  41.        Modifying the Keymask. . . . . . . . . . . . . . . . . . . . . .  21
  42.        Displaying a User Prompt With GETK . . . . . . . . . . . . . . .  21
  43.      SUBSTR (SUBSTRING) FUNCTION. . . . . . . . . . . . . . . . . . . .  22
  44.      LEN (LENGTH) FUNCTION. . . . . . . . . . . . . . . . . . . . . . .  23
  45.      UPPER FUNCTION . . . . . . . . . . . . . . . . . . . . . . . . . .  23
  46.      ECHO FUNCTION. . . . . . . . . . . . . . . . . . . . . . . . . . .  23
  47.   DATE FORMATS. . . . . . . . . . . . . . . . . . . . . . . . . . . . .  24
  48.      SYMBOL CONVENTIONS . . . . . . . . . . . . . . . . . . . . . . . .  24
  49.      PSEUDODATES. . . . . . . . . . . . . . . . . . . . . . . . . . . .  25
  50.   INPUT DATE FORMATS. . . . . . . . . . . . . . . . . . . . . . . . . .  26
  51.      CALENDAR DATE INPUT FORMATS. . . . . . . . . . . . . . . . . . . .  26
  52.      BUSINESS JULIAN DATE INPUT FORMATS . . . . . . . . . . . . . . . .  27
  53.      GETTING DATE/TIME A FILE WAS CREATED . . . . . . . . . . . . . . .  28
  54.   OUTPUT DATE FORMATS . . . . . . . . . . . . . . . . . . . . . . . . .  29
  55.      DAY-OF-WEEK AND MONTH OUTPUT FORMATS . . . . . . . . . . . . . . .  31
  56.      MISCELLANEOUS OUTPUT FORMATS . . . . . . . . . . . . . . . . . . .  31
  57.      LEAP-YEAR FLAG OUTPUT FORMAT . . . . . . . . . . . . . . . . . . .  32
  58.      TIME OUTPUT FORMATS. . . . . . . . . . . . . . . . . . . . . . . .  32
  59.      BUSINESS JULIAN DATE OUTPUT FORMATS. . . . . . . . . . . . . . . .  33
  60.      ABSOLUTE DATE/TIME OUTPUT FORMATS. . . . . . . . . . . . . . . . .  34
  61.      /T: TIME OVERRIDE PARAMETER. . . . . . . . . . . . . . . . . . . .  35
  62.   HOW TO PUT FDATE OUTPUT INTO AN ENVIRONMENT VARIABLE. . . . . . . . .  36
  63.      CALL A BATCH FILE. . . . . . . . . . . . . . . . . . . . . . . . .  36
  64.      USE AN ENVIRONMENT-MANIPULATION UTILITY. . . . . . . . . . . . . .  36
  65.      FDATE'S /V PARAMETER . . . . . . . . . . . . . . . . . . . . . . .  37
  66.      /V WHEN RUNNING UNDER MICROSOFT WINDOWS. . . . . . . . . . . . . .  38
  67.        Turbo Professional: "Highly Recommended" . . . . . . . . . . . .  38
  68.      /V WHEN USING 4DOS, NDOS, AND UMB. . . . . . . . . . . . . . . . .  39
  69.   FDATE'S ERROR HANDLING. . . . . . . . . . . . . . . . . . . . . . . .  40
  70.   EXAMPLES OF HOW TO USE FDATE. . . . . . . . . . . . . . . . . . . . .  41
  71.      :01 Display Fdate output on screen . . . . . . . . . . . . . . . .  41
  72.      :02 Redirect FDATE output to a file. . . . . . . . . . . . . . . .  41
  73.      :03 Put FDATE output in an environment variable using a batch file  41
  74.      :04 Put FDATE output in an environment variable using /V parm. . .  41
  75.      :05 Put FDATE output in an environment variable using STRINGS. . .  41
  76.      :06 Put FDATE output in an environment variable using GET. . . . .  41
  77.      :07 Change a date from one format into another . . . . . . . . . .  41
  78.      :07 Get user input . . . . . . . . . . . . . . . . . . . . . . . .  42
  79.      :08 Get a user menu selection. . . . . . . . . . . . . . . . . . .  43
  80.      :11 Find the difference in days between two dates. . . . . . . . .  44
  81.      :12 Find the elapsed days/hours/minutes between two date/times . .  45
  82.      :13 FORATIM2.BAT . . . . . . . . . . . . . . . . . . . . . . . . .  48
  83.      :14 Time the execution of a piece of software. . . . . . . . . . .  51
  84.      :15 Find calendar date corresponding to a "business Julian" date .  53
  85.      :16 Set your PC's date to a business julian date . . . . . . . . .  54
  86.      :18 Determine if parm %1 contains a valid date . . . . . . . . . .  56
  87.      :19 "Roll your own" date format  . . . . . . . . . . . . . . . . .  57
  88.      :20 Find the 4th Thursday in November (Thanksgiving) . . . . . . .  57
  89.      :22 On a date, show what anniversary it is for some event. . . . .  57
  90.      :23 Show a list of holidays in a given year. . . . . . . . . . . .  57
  91.      :24 Show a list of Federal holidays in a given year. . . . . . . .  57
  92.      :25 Determine if a year is valid, and evenly divisible by 4. . . .  58
  93.      :30 Compare a file's date to today's date. . . . . . . . . . . . .  58
  94.      :31 Compare two files' date/time . . . . . . . . . . . . . . . . .  59
  95.      :32 Display a list of all files that were created/updated today. .  60
  96.      :33 Delete files more than X days old (use a batch-file subroutine) 61
  97.      :34 Loop through an array of environment variables . . . . . . . .  66
  98.      :44 Do something on the last day (or last Friday) of the month . .  67
  99.      :45 Get information about the month prior to the current month . .  68
  100.      :50 Represent a date in 3 bytes of "extended hex" notation . . . .  69
  101.      :51 Represent a date in a short (4-byte) format (technique #1) . .  69
  102.      :52 Represent a date in a short (4-byte) format (technique #2) . .  70
  103.      :54 Customize Fdate for a language of your choice. . . . . . . . .  71
  104.      :55 Fergian.BAT (used in the previous example) . . . . . . . . . .  72
  105.      :58 Convert numbers to . . . . . . . . . . . . . . . . . . . . . .  74
  106.      :61 DO-ONCE: Run apps when booting for the first time of the day .  75
  107.      :62 Run specific software, depending on the day of the week. . . .  76
  108.      :63 Run a program at a specified time later in the day . . . . . .  76
  109.      :66 Change a filename to contain today's date. . . . . . . . . . .  78
  110.      :67 Change a file's name to a name that contains today's date. . .  78
  111.      :68 Change a file's name to a name containing an absolute minute .  78
  112.      :71 Extract the rightmost n characters of a string . . . . . . . .  79
  113.   HOW FDATE THINKS ABOUT DATES. . . . . . . . . . . . . . . . . . . . .  80
  114.      FDATE'S BUSINESS VIEW OF THE CALENDAR. . . . . . . . . . . . . . .  80
  115.      FDATE'S BASE DATE. . . . . . . . . . . . . . . . . . . . . . . . .  80
  116.      FDATE'S LEAP YEAR ALGORITHM. . . . . . . . . . . . . . . . . . . .  81
  117.      FDATE'S CENTURY-ASSUMPTION ALGORITHM . . . . . . . . . . . . . . .  82
  118.      FDATE'S IMPLEMENTATION LIMITS. . . . . . . . . . . . . . . . . . .  82
  119.   DISTRIBUTION ISSUES . . . . . . . . . . . . . . . . . . . . . . . . .  83
  120.      USE, REGISTRATION, AND DISTRIBUTION OF FDATE . . . . . . . . . . .  83
  121.      TECHNICAL SUPPORT FOR FDATE. . . . . . . . . . . . . . . . . . . .  84
  122.      WHERE TO FIND THE MOST CURRENT VERSION OF FDATE. . . . . . . . . .  84
  123.      UPLOADING FDATE TO ELECTRONIC BULLETIN BOARDS. . . . . . . . . . .  84
  124.      CONTENTS OF THE FDATE.ZIP DISTRIBUTION FILE. . . . . . . . . . . .  84
  125.      RECENT FDATE REVISION HISTORY. . . . . . . . . . . . . . . . . . .  85
  126.  
  127. WHAT IS FDATE?
  128. ==============
  129. Fdate is a utility for doing date formatting and date arithmetic in DOS
  130. batch files.  There are a number of different ways to put FDATE's output
  131. into environment variables.  Once this has been done, the environment
  132. variables can be used and manipulated in many ways in the batch file.
  133.  
  134. FDATE is freeware, or what is technically known as "zero-cost shareware". 
  135. There is no requirement to register FDATE in any way.  For more details,
  136. see the DISTRIBUTION ISSUES section.
  137.  
  138. Here are some of the things you can do with FDATE.
  139.  
  140.     accept user input from the keyboard
  141.  
  142.     retrieve today's date in a variety of formats
  143.       place today's date into a file name
  144.  
  145.     reformat dates 
  146.        Output formats include common American and European formats, or you
  147.        can "roll your own" by manipulating environment variables.  Month
  148.        and weekday names can be produced in several languages (English,
  149.        French, German, Spanish).
  150.  
  151.     calculate when certain holidays occur in a given year
  152.  
  153.     do date arithmetic
  154.       determine the date N days before/after a given date
  155.       compare two dates to determine which is earlier
  156.       compare two dates to determine how many days apart they are
  157.  
  158.     determine if a year is a leap year
  159.     determine whether a year is evenly divisible by some number
  160.  
  161.     determine what day of the week a date falls on
  162.       run certain software only on certain days of the week
  163.  
  164.     retrieve the date/time from the date/timestamp of a file
  165.     do simple integer arithmetic (add, subtract, modulus)
  166.     calculate the time a piece of software takes to run
  167.     convert a calendar date to/from a "business julian" date
  168.  
  169.     extract a substring from an environment variable
  170.  
  171.  
  172. OTHER UTILITIES NAMED "FDATE"
  173. =============================
  174.  
  175. There is another shareware utility named FDATE in circulation.  It is an
  176. implementation of the UNIX "touch" utility, and is used to change the
  177. date/time stamp of a file.  
  178.  
  179. Both FDATEs have been in circulation for too long to make it practical to
  180. change the name of either one.  All that can be done is to warn you of a
  181. potentially confusing situation.
  182.  
  183. OVERVIEW OF PARAMETERS
  184. ======================
  185.  
  186. FDATE accepts the following parameters:
  187.  
  188.        /F /A /B /I /O /P /S /N /D /L /V /T /Q
  189.  
  190. If the /F parameter is not present, FDATE displays a help screen.  
  191.      If you get FDATE's help screen when you don't expect it, you probably
  192.      forgot to specify the /F parameter or mistyped it.
  193.  
  194. Parameters can be in any order and upper or lower case.
  195.      Note that although function and format parms are not case sensitive,
  196.      they are "text sensitive".  If any characters are missing, added, or
  197.      mistyped, the parameter will be rejected.
  198.  
  199. What parameters are required (other than /F) depends on the function
  200. requested with the /F parameter.  Unnecessary parameters are simply
  201. ignored.
  202.  
  203.  
  204.  
  205. The next page contains a brief description of what each of the parameters
  206. means.
  207.  
  208. /F   requests a particular FDATE function.  This is Fdate's most important
  209.      parameter.  See the OVERVIEW OF FUNCTIONS section, and the detailed
  210.      description of each Fdate function.
  211.  
  212. /N   number of days (always a number)
  213.  
  214. /D   day-of-week number (used only with W function)
  215.  
  216. /A   For date functions, these two parameters are used to specify dates. 
  217. /B   For the ordinary arithmetic functions, these parameters are used to
  218.      specify numbers.  For date functions, if either of these parameters is
  219.      omitted, it defaults to today's date.
  220.  
  221. /T   For date functions, /T overrides the time portion of the date on the
  222.      /A parm. (Note that it does NOT override the time portion of the date
  223.      on the /B parm.)  
  224.  
  225. /I   specifies format of input date(s)
  226.      If the /I parameter is omitted, /Imm-dd-ccyy is assumed.
  227.  
  228. /O   specifies format of output date
  229.      If the /O parameter is omitted, /Od1 is assumed.
  230.  
  231. /L  specifies language of output.
  232.      /Lus   US (American) English-language output
  233.      /Lfr   French-language output
  234.      /Lgr   German-language output
  235.      /Lsp   Spanish-language output
  236.      If the /L parameter is omitted, /Lus [American English] is assumed.
  237.  
  238. /V   specifies that output is to be placed in an environment variable
  239.      rather than written to standard output.
  240.      If /V is specified but not followed by the name of an environment
  241.      variable, then /Vfdate is assumed, and output is placed in the FDATE
  242.      environment variable.
  243.  
  244. /Q   specifies a prompt string for a GET, GETU, or GETK function, or the
  245.      input string for a string-handling function (SUBSTR, LEN, UPPER).
  246.  
  247. /P   specifies a prefix string for the output
  248. /S   specifies a suffix string for the output
  249.      These optional parameters may always be specified or omitted.
  250.      They must be enclosed in single quotes, double quotes, or
  251.                   square brackets
  252.  
  253.      Note that "whitespace" will be removed from these strings, so
  254.      formatting of /P and /S strings cannot be controlled using spaces.  To
  255.      format strings, use periods or ASCII 255 (hex'ff') as filler.
  256.  
  257.        EXAMPLES
  258.           FDATE /Ff                /P"Today is "
  259.           FDATE /Fdif /B12-25-TTTT /P"It is " /S" days until Christmas"
  260.  
  261. OVERVIEW OF FUNCTIONS
  262. =====================
  263.  
  264. Fdate's most important parameter is the function parameter, /F.  Here is a
  265. brief summary of the functions that may be specified on the /F parm, for
  266. example: /Fadd.  Detailed descriptions of each of the functions can be
  267. found on the next few pages.
  268.  
  269. If the /F parameter is omitted, it defaults to the null string, which
  270. causes Fdate to display its HELP screens.
  271.  
  272. f         Format the date in the /A parm into format specified in /O parm
  273.  
  274. add       Add the number of days in the /N parm to the date in the /A parm
  275.  
  276. sub       Subtract the number of days in the /N parm from the date in the
  277.           /A parm
  278.  
  279. dif       Return the number of days between dates in the /A and /B parms
  280.  
  281. w         Do date arithmetic in terms of weeks rather than days.  Using the
  282.           date in the /A parm, a number specified in the /N parm, and a
  283.           day-of-the-week number specified in the /D parm, return the date
  284.           of the /Nth /Day-of-the-week before (or after) /Adate.  
  285.  
  286. m         Do date arithmetic in terms of months rather than days.  Add the
  287.           number of months in the /N parm to the date in the /A parm.  /N
  288.           may be a negative number.
  289.  
  290. STRING-HANDLING FUNCTIONS
  291.  
  292. get       get user input from the keyboard, and produce it as output
  293.           Optionally, display a prompt string.
  294.  
  295. getu      same as get, but produce output converted to upper case
  296.  
  297. getk      get a keypress and produce it (converted to upper case)
  298.  
  299. len       produce the length of a string in the /Q parm
  300.  
  301. upper     convert the string in the /Q parm to upper case
  302.  
  303. e         Echo the strings on the /P and /S parameters.
  304.  
  305. substr    Extract a substring from the /Q parm, starting in column
  306.           specified on /A parm, for a length specified on /B parm.
  307.  
  308. DATE/TIME COMPARISON FUNCTIONS
  309.  
  310. comp      Compare the dates in the /A and /B parms. Return LT, EQ, or GT.
  311.  
  312. tcomp     Compare the times specified on the /A and /B parms.
  313.  
  314.  
  315. ORDINARY (AS OPPOSED TO DATE) ARITHMETIC FUNCTIONS
  316.  
  317.           Functions whose names begin with "#" do ordinary arithmetic, i.e.
  318.           arithmetic on numbers rather than dates.
  319.  
  320. #add      Add the integers specified on the /A and /B parms.  To do
  321.           subtraction, add a negative number to a positive number.
  322.  
  323. #dif      returns the difference between the integers specified on the /A
  324.           and /B parms. 
  325.  
  326. #comp     Compare the integers specified on the /A and /B parms.  Return
  327.           LT, EQ, or GT.
  328.  
  329. #mod      Modulus.  Divide the integer on the /A parm by the integer on the
  330.           /B parm, and return the remainder.  
  331.  
  332. #mult     Multiply the integer on the /A parm by the integer on the /B
  333.           parm, and return the result.
  334.  
  335. #div      Divide the integer on the /A parm by the integer on the /B parm,
  336.           and return the result as a decimal number with two decimal
  337.           places.
  338.  
  339. #idiv     Integer division. Divide the integer on the /A parm by the
  340.           integer on the /B parm, and return the result as an integer.
  341.  
  342. #2xx      Convert an integer in the range of 0-35 to "extended hex" (XX)
  343.           notation.
  344.  
  345. FUNCTIONS: DETAILED DESCRIPTIONS
  346. ================================
  347.  
  348.  
  349. DATE FORMATTING FUNCTIONS
  350. =========================
  351.  
  352. FUNCTION  FDATE /Ffunc /Adate /Iformat /Oformat
  353. --------  -------------------------------------------
  354. format    this is a synonym for function "f"
  355.  
  356. f         returns /Adate in format specified by /Oformat
  357.           Since /Aformat and /Oformat can be different, the FORMAT
  358.           function is used to change a date from one format to another.
  359.           Because of the wide variety of output formats, the FORMAT
  360.           function can also be used to determine the day of week of the
  361.           date, whether the date is in a normal or leap year, etc.
  362.  
  363. EXAMPLES
  364.           FDATE /Ff /A19920101 /Iccyymmdd /O"mn zd, ccyy"
  365.           FDATE /Ff       /Atoday         /Od1
  366.           FDATE /Fformat  /Atoday         /Od1
  367.           FDATE /Ff /If /Afdate.exe /P"FDATE.EXE last updated: " /Ofull
  368.  
  369. DATE ARITHMETIC FUNCTIONS
  370. =========================
  371.  
  372. Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
  373. which means that Fdate can accept numbers up to 9 digits long.
  374.  
  375. FUNCTION  FDATE /Ffunc /Nnumdays /Adate /Iformat /Oformat
  376. --------  -------------------------------------------
  377. add       Adds      /Ndays to   /Adate, produces date in /Oformat format
  378. sub       Subtracts /Ndays from /Adate, produces date in /Oformat format
  379.  
  380.           EXAMPLES
  381.           FDATE /Fadd /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
  382.           FDATE /Fsub /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
  383.           FDATE /Fadd /N90 /Atoday                   /Od1
  384.  
  385. dif       Returns number of days between /Adate and /Bdate
  386.           Order of the two dates is not significant.
  387.  
  388.           NOTE THAT:
  389.           For DIF, both dates must be in the SAME format, the input format
  390.           specified in /Iformat.  If the two dates are not in the same
  391.           format, you must first reformat one of the dates using the /Ff
  392.           function, then use DIF to get their difference.
  393.  
  394.           EXAMPLES
  395.           FDATE /Fdif /A01-01-1992 /B11-11-1992  /Imm-dd-ccyy
  396.           FDATE /Fdif /A11-11-1992 /B01-01-1992  /Imm-dd-ccyy
  397.           FDATE /Fdif /Atoday      /B01-01-1992  /Imm-dd-ccyy
  398.  
  399. MONTH DATE ARITHMETIC FUNCTIONS
  400. ===============================
  401.  
  402. FUNCTION  FDATE /Ffunc /Nnumdays /Adate /Iformat /Oformat
  403. --------  -------------------------------------------
  404. m         [month arithmetic]
  405.  
  406.           This function adds /N months to /Adate, and produces a date in
  407.           /Oformat format.  It can be used to do monthly subtraction by
  408.           making the number in the /N parameter a negative number.
  409.  
  410.           EXAMPLES
  411.  
  412.           FDATE /Fm /N1  /A03-15-1992 /Imm-dd-ccyy /Omm-dd-ccyy
  413.                   produces:   04-15-1992
  414.  
  415.           FDATE /Fm /N-1 /A03-30-1991 /Imm-dd-ccyy /Omm-dd-ccyy
  416.                   produces:   02-28-1991
  417.  
  418.           FDATE /Fm /N-1 /A03-30-1992 /Imm-dd-ccyy /Omm-dd-ccyy
  419.                   produces:   02-29-1992
  420.  
  421.  
  422.           Note that a too-simple algorithm for month arithmetic can produce
  423.           non-existent dates.  Subtracting a month from March 30, 1991 (as
  424.           in the second example) could produce a result of February 30,
  425.           1991, a date which cannot exist.  
  426.  
  427.           Fdate's month arithmetic is more sophisticated than that.  If
  428.           Fdate finds that a simple month-arithmetic operation produces an
  429.           invalid date, it subtracts the minimum number of days required to
  430.           produce a valid date.  
  431.  
  432.           Thus, in the second example, it produces February 28, 1991, the
  433.           last date in February, 1991.  In the third example, it produces
  434.           February 29, 1992 because 1992 is a leap year.  
  435.  
  436.  
  437. Note that telling Fdate to add 12 months to February 29, 1992 produces a
  438. result of February 28, 1993, since 1993 is not a leap year.  See Peter G.
  439. Neumann's INSIDE RISKS column in COMMUNICATIONS OF THE ACM, June 1992 (Vol.
  440. 35, No. 6), entitled "Leap-Year Problems":
  441.  
  442.   Prime Computer's MAGSAV failed at midnight [on Feb 29, 1992]...  G. M.
  443.   Lack noted that MAGSAV probably failed on leap-day because it tried to
  444.   increment the year by one to set a tape label expiration date, and the
  445.   resulting nonexistent date of Feb 29, 1993 threw it for a loop.
  446.  
  447. WEEKDAY DATE ARITHMETIC FUNCTIONS
  448. =================================
  449.  
  450. FUNCTION  FDATE /Ffunc /Adate /Iformat /Oformat /Ddow#  /Ndow-count
  451. --------  -----------------------------------------------------------
  452. w         [week arithmetic]
  453.           This function provides a way of doing date arithmetic in terms of
  454.           weeks rather than days.
  455.  
  456.           This function accepts a date specification in parm /A and
  457.           returns the date of the /Nth /Day-of-the-week
  458.           before or after /Adate.  For example:
  459.  
  460.           If    /A specifies November 14, 1992
  461.                 /D specifies the number for Thursday (i.e., 5)
  462.                 /N specifies a week count of 3
  463.           then /Fw returns the date of the third Thursday after
  464.           November 14, 1992. (See full example, below)
  465.  
  466.           Note that /N may be negative.  If, in the above example, /N
  467.           is specified as -3, then Fdate returns the date of the third
  468.           Thursday BEFORE November 14, 1992.
  469.  
  470.           If the date specified on the /A parms falls on the same day
  471.           of the week as was specified on the /D parm, then that will
  472.           be considered to be the first date meeting that day-of-week
  473.           criterion.  That is, if November 14, 1992 fell on a
  474.           Thursday, and if /N was 1 or -1, then the output date would
  475.           be the same as the input date, i.e.  November 14, 1992.
  476.  
  477.           The acceptable values for /N (number of weeks) is in
  478.           the range of 99..-99.  A value of zero (i.e. /N0) is invalid.
  479.  
  480. EXAMPLES
  481.      find date of Thanksgiving (4th Thursday in November) in 1992
  482.          FDATE /Fw /A11-01-1992 /Imm-dd-ccyy /D5 /N4 /Od1
  483.      returns: Thursday November 26, 1992
  484.  
  485.      find the beginning of the work-week (Monday, 2nd day of week)
  486.      AFTER Thanksgiving, 1992
  487.          FDATE /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N1 /Od1
  488.  
  489.      find the beginning of the work-week (Monday, 2nd day of week)
  490.      BEFORE Thanksgiving, 1992
  491.          FDATE /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N-1 /Od1
  492.  
  493.      get last Friday's date
  494.         rem Find next Friday's date (or today's date, if today is Friday).
  495.         rem Then find the Friday that precedes that Friday.
  496.         FDATE /Fw /At        /Omm-dd-ccyy  /D6 /N+1  /V
  497.         FDATE /Fw /A%fdate%  /Imm-dd-ccyy  /D6 /N-2  /V
  498.         Echo Last Friday was %fdate%
  499.  
  500. DATE/TIME COMPARISON FUNCTIONS
  501. ==============================
  502.  
  503. FUNCTION  FDATE /Ffunc /Adate /Bdate /Iformat
  504. --------  -------------------------------------------
  505. comp      compares the dates (time granularity = 1 day)
  506.           specified on the /A and /B parms.
  507.           returns         when
  508.             LT            /A  is less than    (earlier than) /B
  509.             EQ            /A  is equal to     (same as)      /B
  510.             GT            /A  is greater than (later than)   /B
  511.  
  512.           In addition, the errorlevel is set to a special value:
  513.             LT = 101     EQ = 102     GT = 103
  514.  
  515.  
  516.  
  517. tcomp     compares the times (time granularity = 1 second)
  518.           specified on the /A and /B parms.
  519.           This is useful when input format /If (file) is specified.
  520.           It can be used to compare the timestamps of two files and
  521.           determine which is older.
  522.               EXAMPLE: Fdate /Ftcomp /If /Amyfile.1 /Byourfile.1
  523.  
  524.           returns         when
  525.             LT            /A  is less than    (earlier than) /B
  526.             EQ            /A  is equal to     (same as)      /B
  527.             GT            /A  is greater than (later than)   /B
  528.  
  529.           In addition, the errorlevel is set to a special value:
  530.             LT = 101     EQ = 102     GT = 103
  531.  
  532.  
  533.  
  534. COMPARE-FUNCTION ERRORLEVELS
  535. ============================
  536.  
  537. Starting with version 8.3, Fdate's "comparison" functions (comp, tcomp,
  538. #comp) return distinct errorlevels as well as distinct output strings:
  539.  
  540.           returns         errorlevel
  541.             LT            101
  542.             EQ            102
  543.             GT            103
  544.  
  545. NUMERIC ARITHMETIC FUNCTIONS
  546. ============================
  547.  
  548. Note that all of Fdate's arithmetic functions operate on integers.  A
  549. decimal number on an input parameter will be rejected, and an error message
  550. will be displayed.
  551.  
  552. FUNCTION  FDATE /Ffunc /Anum  /Bnum
  553. --------  -------------------------------------------
  554.  
  555. #add      returns the sum of the integers specified
  556.           on the /A and /B parms.  Can be used to calculate the
  557.           "absolute" minute(second, date) in the future from a given
  558.           "absolute" minute(second, date).   Also useful in generating
  559.           sequences of numbers and looping (see EXAMPLES).
  560.  
  561. #sub      (not supported)
  562.           Fdate does not provide a numeric subtraction operation as such. 
  563.           To do subtraction, add two numbers, one of which is a negative
  564.           number.  For example, to subtract 3 from 2:
  565.               FDATE /F#add /A2 /B-3          [ returns: -1 ]
  566.  
  567. #dif      returns the difference between the integers specified on the /A
  568. and /B parms.  #dif is the same as subtraction in which the
  569. smaller number is subtracted from the larger number; it will
  570. never return a negative number.  It can be used to calculate the 
  571. number of minutes(seconds, days) between two "Absolute"
  572. minutes(seconds, dates).
  573.  
  574. #comp     compares the integers specified on the /A and /B parms.
  575.           returns         when
  576.             LT            /A  is less    than /B
  577.             EQ            /A  is equal   to   /B
  578.             GT            /A  is greater than /B
  579.  
  580.           In addition, the errorlevel is set to a special value:
  581.             LT = 101     EQ = 102     GT = 103
  582.  
  583. #mod      divides the integer on the /A parm by the integer on the /B parm,
  584.           and returns the remainder.  
  585.  
  586.           This is useful for determining whether a number is evenly
  587.           divisible by some other number.  If the remainder is 0, then /A
  588.           is evenly divisible by /B.  If a year is evenly divisible by 4,
  589.           for example, then it is an American election year.  If it is
  590.           evenly divisible by 100, then it is a century year, etc.
  591.  
  592.  
  593. #mult     multiplies the integer on the /A parm by the integer on the /B
  594.           parm, and returns the result.
  595.  
  596. #div      (division) divides the integer on the /A parm by the integer on
  597.           the /B parm, and returns the result as a decimal number, with two
  598.           digits to the right of the decimal.
  599.  
  600.           This is useful for dividing a number (representing the number of
  601.           minutes in some period) by 60 to get the length of the period
  602.           expressed in terms of hours, or by 1440 to get the length of the
  603.           period expressed in terms of days.  Or you could divide a number
  604.           of days by 7 to get the number of weeks, etc.
  605.  
  606.  
  607. #idiv     (integer division) divides the integer on the /A parm by the
  608.           integer on the /B parm, and returns the result as an integer.
  609.  
  610.           This is useful, especially in conjunction with the #mod function,
  611.           for converting a number of minutes into a number of hours and
  612.           minutes, or days and hours and minutes.  See the EXAMPLES
  613.           section, below.
  614.  
  615. #2xx      (convert number to "extended hex" format)
  616.           "Extended hexadecimal" (XX) notation uses all of the digits, and
  617.           all of the letters of the alphabet, to express numbers in the
  618.           range of 0 to 35 as a single character.  
  619.  
  620.           This function takes a number supplied on parameter /A, and
  621.           returns a single character in extended hex notation.  The input
  622.           number should be in the range of 0-35.  A number of less than 0
  623.           or larger than 35 is rejected as an error (returns "ERROR" and
  624.           errorlevel of 1).
  625.  
  626.           EXAMPLE: Fdate /F#2xx /A35    =====> returns the letter Z
  627.  
  628. DATE VALIDATION FUNCTION
  629. ========================
  630.  
  631. v    If the date specified on the /A parm is valid, produces "" (the null
  632.      string).  Otherwise, produces "ERROR" and a non-zero errorlevel by
  633.      triggering Fdate's error-handling function.  (See the section on
  634.      FDATE'S ERROR HANDLING, later in this documentation.)
  635.  
  636.      When using the /Fv parameter, you will almost always want to check
  637.      success of the date validation by checking the errorlevel, and to
  638.      redirect Fdate's output to NUL (so that when it writes the null
  639.      string, it does not produce a blank line on your screen).
  640.  
  641.      When processing an input date, Fdate does not reject all invalid
  642.      dates: specifically, it is very forgiving about the number in the day-
  643.      of-the-month part of input dates.  It will accept, for example,
  644.      19931144 (November 44, 1993 in CCYYMMDD format) and process it quite
  645.      happily (as December 14, 1993).  This is not a bug, it is a feature. 
  646.      This feature provides one way (admittedly a crude one) of doing date
  647.      arithmetic.  The date part (JJJ) of a Business Julian input date can
  648.      be used in the same way.  
  649.  
  650.      This feature can be a drawback, however, if you want to be sure that
  651.      some date (say a date that a user entered as an input parameter) is
  652.      valid.  The /Fv function provides a way of completely checking a date
  653.      for validity.  It will, for example, reject November 44, 1993 as
  654.      invalid. 
  655.  
  656.  
  657. STRING FUNCTIONS
  658. ================================
  659.  
  660. GET and GETU (GET USER INPUT) FUNCTIONS
  661. =======================================
  662.  
  663. get  get user input
  664. getu get user input (uppercase)
  665.  
  666.      These functions wait for the user to enter an input string, terminated
  667.      by a press of the ENTER key.  Then Fdate simply produces that same
  668.      input string (or in the case of GETU, that input string in all upper
  669.      case) as its output.  
  670.  
  671.      If the /Q prompt-string parameter is specified, then the prompt string
  672.      is displayed, but a NEWLINE is not written to the screen before
  673.      waiting for the user's input.
  674.  
  675.      As with Fdate's other forms of output, this output can be displayed,
  676.      redirected to a file, or (if your environment supports Fdate's /V
  677.      parameter) placed into an environment variable.
  678.  
  679.      This "get" function provides no edit mask for input -- Fdate will
  680.      accept anything.  The situation is helped by the fact that Fdate also
  681.      provides a validate function (/Fv) which can be used to validate the
  682.      user input, so that one can:
  683.  
  684.           1.   use /Fget to get user input and place it in an environment
  685.                variable 
  686.           2.   use /Fv to validate the date in the Evar
  687.           3.   use the rest of the batch file to process the user input
  688.  
  689.      See examples: "Get user input" and FORATIM2.BAT
  690.  
  691.      For a program that provides more sophisticated functions for getting
  692.      user input in batch files (type checking, edit masks, etc.), I
  693.      recommend Bob Stephan's shareware program GET, which is described
  694.      elsewhere in this documentation.
  695.  
  696. GETK (GET KEYPRESS) FUNCTION
  697. =======================================
  698. getK get keypress 
  699.  
  700.      This function waits for the user to press an acceptable key, then
  701.      produces the key as its output.  If the key pressed is a letter, then
  702.      the letter is returned IN UPPER CASE.  This feature is designed to
  703.      support simple "pick a menu selection" processing in batch files.
  704.  
  705.      The GETK function takes a /K "keymask" parameter that tells it which
  706.      keys to accept.  If the user presses an unacceptable key (i.e. one
  707.      that is not in the keymask), the keypress is ignored.
  708.  
  709.      If no /K parm is specified, the default keymask is:
  710.              ABCDEFGHIJKLMNOPQRSTUVWXYZx
  711.      That is, the default keymask will accept letters and the ESCAPE key.
  712.  
  713.   Specifying the Keymask
  714.  
  715.      NOTE THAT THE VALUES SPECIFIED ON THE /K PARM ARE CASE-SENSITIVE.  
  716.  
  717.      The keymask may contain numbers, uppercase letters, and any of the
  718.      other printable characters on the keyboard.  
  719.  
  720.      There is no way to tell FDATE to accept "special" keypresses such as
  721.      function keys, ALT or CONTROL keys, arrow keys, etc.
  722.  
  723.      If the keymask contains an uppercase letter (e.g. "A"), and the user
  724.      presses the corresponding unshifted letter (e.g. "a"), then the
  725.      keypress will be accepted and the uppercase letter will be returned.
  726.  
  727.      The keymask may contain the following lowercase letters, which have
  728.      special meanings:
  729.  
  730.        x  represents the ESCAPE key
  731.        e  represents the ENTER (RETURN) key
  732.        z  [a place-holder character]
  733.  
  734.             Lowercase "z" will be ignored when FDATE decides which
  735.             keypresses are acceptable.  Its presence in the keymask will
  736.             affect the positions of other characters in the keymask, and
  737.             hence the ERRORLEVEL that FDATE returns when the user presses
  738.             an acceptable key.  (For the uses of "z", see "GetK Results
  739.             also in ERRORLEVEL" and "Modifying the Keymask", below.)
  740.  
  741.      All other lowercase letters are reserved for possible future use.  In
  742.      the current release of FDATE, they are treated like lowercase "z".
  743.  
  744.      EXAMPLE:  If a keymask of "/kXx" was specified, then if the user
  745.                pressed the (shifted or unshifted) "X" key, then uppercase
  746.                "X" would be returned.  If he pressed the ESCAPE key, then
  747.                lowercase "x" would be returned.
  748.  
  749.   GetK Results also in ERRORLEVEL
  750.  
  751.      When the GETK function returns a key, it sets the DOS errorlevel to a
  752.      value corresponding to the position of that key in the keymask.  For
  753.      example, with keymask of "/kABx", if the user presses:
  754.  
  755.           "A": value returned will be "A", errorlevel will be 1
  756.           "B": value returned will be "B", errorlevel will be 2
  757.        ESCAPE: value returned will be "x", errorlevel will be 3
  758.  
  759.      If the user presses CONTROL+BREAK, FDATE will abort and return
  760.      errorlevel 255.
  761.  
  762.      Here is an example batch file:
  763.      ==================================================================
  764.      @echo off
  765.      cls
  766.      echo Demonstration of FDATE's GETK (get keypress) function
  767.      echo Press CONTROL+BREAK to end
  768.      :top
  769.      echo.
  770.      fdate /fGetK /P"You pressed: " /Q"Press a key: "  /K"12ABxe "
  771.      if errorlevel 1  if not errorlevel 2  echo errorlevel : 1
  772.      if errorlevel 2  if not errorlevel 3  echo errorlevel : 2
  773.      if errorlevel 3  if not errorlevel 4  echo errorlevel : 3
  774.      if errorlevel 4  if not errorlevel 5  echo errorlevel : 4
  775.      if errorlevel 5  if not errorlevel 6  echo errorlevel : 5
  776.      if errorlevel 6  if not errorlevel 7  echo errorlevel : 6
  777.      if errorlevel 7  if not errorlevel 8  echo errorlevel : 7
  778.      if errorlevel 255 echo ERRORLEVEL 255
  779.      if errorlevel 255 goto endit
  780.      goto top
  781.      :endit
  782.      ==================================================================
  783.  
  784.      Note that the keymask may contain blanks if the keymask is enclosed in
  785.      quotes (as in this example batch file).  But remember that Fdate
  786.      eliminates redundant spaces when obtaining its parameter input, so you
  787.      should never include more than one blank in your keymask.
  788.  
  789.   Modifying the Keymask
  790.  
  791.      It it is often necessary to make program modifications during the life
  792.      of a batch file.  If you are using the GETK function and testing the
  793.      errorlevel rather than the environment, then the insertion or deletion
  794.      of characters into the existing keymask will change the errorlevels
  795.      returned by the following characters in the keymask.  This will force
  796.      you to re-write the errorlevel tests, which may be a big job if the
  797.      keymask is long.
  798.  
  799.      Here are some tips on how to avoid this work:
  800.  
  801.          When ADDING a character to the keymask, always add it a the END
  802.           of the keymask.
  803.  
  804.          When DELETING a character from the keymask, do not actually
  805.           delete it.  Instead, replace it by a lowercase "z".
  806.  
  807.  
  808.  
  809.   Displaying a User Prompt With GETK
  810.  
  811.      The /Q (user prompt) parameter is especially handy when used in
  812.      conjunction with the GETK function.  If the /Q prompt-string parameter
  813.      is specified (as in the example batch file, above), then the prompt
  814.      string is displayed, but a NEWLINE is not written to the screen before
  815.      waiting for the user's keypress.
  816.  
  817.      For a program that provides more sophisticated "get key" functions for
  818.      batch files, I recommend Bob Stephan's shareware program GET, which is
  819.      described elsewhere in this documentation.
  820.  
  821. SUBSTR (SUBSTRING) FUNCTION
  822. ===============================
  823.  
  824. substr
  825.      This function returns a substring of the string supplied in the /Q
  826.      parm, starting in the column supplied in the /A parm, for a length
  827.      supplied in the /B parm.  
  828.  
  829.      The start column specified in the /A parm may be a negative number; if
  830.      it is, then the start column is calculated from the end of the string
  831.      rather than from the beginning.  This feature makes it easy to extract
  832.      the rightmost characters of a string.  
  833.  
  834.                Specifically, when the ParmA is negative, the start position
  835.                is calculated using the following formula:
  836.  
  837.                       StartColumn = length(ParmQ) + 1 + ParmA
  838.  
  839.                Example:   Fdate /Fsubstr  /A-2  /Qabcd
  840.                       StartColumn = length(ParmQ) + 1 + ParmA
  841.                       StartColumn =      4        + 1 + (-2)     = 3  
  842.  
  843.      If /Q is omitted, Fdate reports an error.
  844.  
  845.      If /A is zero, Fdate reports an error.
  846.      If /A is omitted, it defaults to 1 (that is, the start of the string).
  847.      If /A is negative,  and longer than the length of the string, then the
  848.                          start column is 1 (the start of the string)
  849.  
  850.      If /B (length) is so great that it exceed the length of the /Q input
  851.      string, then only the remainder of the string is returned.
  852.  
  853.      If /B is zero, Fdate returns a null string.
  854.      If /B is omitted, it defaults to 999.
  855.  
  856.      EXAMPLES:
  857.           Fdate /Fsubstr /A7 /B2 /Q"STEVE FERG"   ===> "FE"
  858.           Fdate /Fsubstr /A7     /Q"STEVE FERG"   ===> "FERG"    
  859.           Fdate /Fsubstr     /B5 /Q"STEVE FERG"   ===> "STEVE"   
  860.  
  861.      EXAMPLES using a negative start position:
  862.           Fdate /Fsubstr /a-6 /B3 /Q"1994 Jun 03"   ===> "Jun         
  863.  
  864.           rem extract the rightmost 6 characters of a string
  865.           Fdate /Fsubstr /a-6     /Q"1994 Jun 03"   ===> "Jun 03"     
  866.  
  867.      REMEMBER that Fdate eliminates redundant spaces when obtaining its
  868.      parameter input:
  869.  
  870.           Fdate /Fsubstr /A7     /Q"STEVE FERG"      ===> "FERG" 
  871.           Fdate /Fsubstr /A7     /Q"STEVE  FERG"     ===> "FERG" 
  872.           Fdate /Fsubstr /A7     /Q"STEVE    FERG"   ===> "FERG" 
  873.  
  874. LEN (LENGTH) FUNCTION
  875. =====================
  876.  
  877. len       Produces a number that is the length of the string on the /Q
  878.           parm.
  879.  
  880.  
  881. UPPER FUNCTION
  882. ===============
  883.  
  884. upper     Produces the string on the /Q parm, converted to upper case.
  885.  
  886.  
  887.  
  888. ECHO FUNCTION
  889. =============
  890.  
  891. e         Produces only the strings specified using the /P and /S
  892.           parameters.
  893.  
  894. You can use /Fe for situations in which you want Fdate to produce output
  895. that doesn't include any sort of date.  In these cases, Fdate functions
  896. just like the DOS "echo" command.  
  897.  
  898. The real use for /Fe is in conjunction with /V, where it can be used to
  899. manipulate the environment in ways that DOS's SET command cannot:
  900.  
  901.   (1)  to give a value to an environment variable that it would not accept
  902.        from the SET command (e.g. a value that contained "=").
  903.  
  904.   (2)  to redirect or pipe a character-string that contains a redirection
  905.        symbol ">" or pipe symbol "|".
  906.  
  907. This feature is for real batch-file power users.
  908.  
  909.  
  910. EXAMPLE BATCH FILE
  911. ------------------
  912.   @ECHO OFF
  913.   set pct=%%%
  914.   Fdate /Fe /P"=Sam=" /vName
  915.   Fdate /Fe /P"echo ECHO Hi, %pct%Name%pct%!>junk2.bat">junk1.bat
  916.      :  RESULT: TEXT OF JUNK1.BAT IS
  917.      :          echo ECHO Hi, %Name%!>junk2.bat
  918.   call junk1.bat
  919.      :  RESULT: TEXT OF JUNK2.BAT IS
  920.      :          ECHO Hi, =Sam=!
  921.   call junk2.bat
  922.      :  RESULT: TEXT DISPLAYED ON SCREEN IS
  923.      :          Hi, =Sam=!
  924.   :endit
  925.  
  926. DATE FORMATS
  927. ============
  928.  
  929. SYMBOL CONVENTIONS
  930. ==================
  931.  
  932. The following symbols are used in specifying date formats:
  933.  
  934. SYMBOL  EXAMPLE   MEANING
  935. ------  -------   -------------------------------------
  936. cc        19      century
  937. yy        93      year
  938. mm        02      month
  939. zm         2      month without leading zero
  940. dd        08      day
  941. zd         8      day   without leading zero
  942. mn       February month name
  943. mn3      Feb      month name, first 3 characters only
  944. dow      Tuesday  day of week
  945. dow3     Tue      day of week, first 3 characters only
  946. dow#      3       day of week as a number (Sunday=1, Monday = 2, etc.)
  947. today             is a "pseudodate" representing the current date
  948. t                 is an alias for the "today" pseudodate
  949. hh:mm    09:05    hours and minutes
  950. hhmm     0905     hours and minutes
  951. ss        13      seconds
  952.  
  953.  
  954.  
  955. PSEUDODATES
  956. ===========
  957.  
  958. t (or today)
  959.           can be used with either /A or /B, e.g. /Atoday or /At.
  960.           This is the default for both /A and /B.  That is, if /A is not
  961.           specified, /At is assumed, and the same for /B.
  962.  
  963.           NOTE THAT
  964.           "Today" as a date specification operates independently of any
  965.           input format.  You need to specify an input format (either
  966.           explicitly via the /I parameter, or implicitly by accepting the
  967.           default value of /I) only for input dates that are supplied to
  968.           Fdate in some other way than via the "today" pseudodate: as a
  969.           date literal, a filename, etc.
  970.  
  971. EXAMPLES:
  972.           rem Get the date that is 90 days from today
  973.           FDATE /Fadd /N90 /Atoday /Omm-dd-ccyy
  974.           FDATE /Fadd /N90 /At     /Omm-dd-ccyy
  975.  
  976.           rem determine if this year is a leapyear
  977.           FDATE /Ff /At /OLY
  978.  
  979.  
  980.  
  981.  
  982. tttt      When used in place of a 4-digit CCYY string, "tttt"
  983.           will cause Fdate to use today's 4-digit year (CCYY).
  984.  
  985. tt        When used in place of a 2-digit DD, MM, or YY string,
  986.           "tt" will cause Fdate to use today's day-of-the-month,
  987.           month, or 2-digit year, respectively.
  988.  
  989.           Note that "tt" can NOT be used for the YY portion of a CCYY
  990.           input year.  The following, for example, is NOT valid:
  991.                FDATE /Ff /Imm-dd-ccyy /A01-01-19tt /Od1
  992.  
  993. EXAMPLES:
  994.  
  995.      FDATE /Ff /Imm-dd-ccyy /A01-01-tttt
  996.      FDATE /Ff /Imm-dd-yy   /A01-01-tt 
  997.  
  998.      rem report the 15th day of this month, this year
  999.      FDATE /Ff /Imm-dd-ccyy /Att-15-tttt
  1000.  
  1001.      rem Show the first Monday in the second quarter of this year
  1002.      FDATE /Fw /Iccyymmdd /Atttt0401 /D2 /N1  /P"First Monday in QTR#2: "
  1003.  
  1004.      rem Show the last Friday on/before the 15th of this month.
  1005.      FDATE /Fw /Iccyymmdd /Atttttt15 /D6 /N-1 /P"Friday before the 15th: "
  1006.  
  1007.  
  1008. INPUT DATE FORMATS
  1009. ==================
  1010.  
  1011.  
  1012. CALENDAR DATE INPUT FORMATS
  1013. ===========================
  1014.  
  1015. FORMAT      EXAMPLES      DISCUSSION
  1016. ------      ---------     -----------------------------
  1017. ccyymmdd    19922002  
  1018.  
  1019.  
  1020. On the /I (input format) parm, the separator character of the following
  1021. input formats must be a dash.  This simply tells Fdate that the input
  1022. date will contain SOME separator character.  The separator character that
  1023. actually occurs in dates in the /A and /B parms is ignored, and may be
  1024. any non-numeric character: a slash "/", a dash "-", a dot ".", etc.
  1025.  
  1026. In specifications that begin with "mm-dd" or "dd-mm", leading zeros need
  1027. not be present in the "mm" and "dd" part of the date.
  1028.  
  1029. ccyy-mm-dd  1992-02-20    Leading zeros MUST be present, since the
  1030.             1992/02/20    date does not begin with dd-mm or mm-dd.    
  1031.             1992.02.20    
  1032.  
  1033.  
  1034. mm-dd-ccyy  02-20-1992    
  1035.             02/20/1992    The dash represents ANY non-numeric character.
  1036.  
  1037.              2-5-1992     Leading zeros need not be present.
  1038.              2/5/1992
  1039.  
  1040. mm-dd-yy    02-05-92      February 5, 1992.  See discussion of
  1041.              2/5/92       FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1042.  
  1043.                           ---------------------------------------
  1044.                           In the following formats, days
  1045.                           precede months  (European style)
  1046.                           ---------------------------------------
  1047.  
  1048. dd-mm-ccyy  05-02-1992 
  1049.             05/02/1992 
  1050.  
  1051.              5-2-1992     Leading zeros need not be present.
  1052.              5/2/1992
  1053.  
  1054. dd-mm-yy    05-02-92      February 5, 1992.  See discussion of
  1055.              5/2/92       FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1056.  
  1057. BUSINESS JULIAN DATE INPUT FORMATS
  1058. ==================================
  1059.  
  1060. These are formats for "business julian" dates: dates expressed as the
  1061. number of days from the beginning of the year, when January 1 is day 1.
  1062.  
  1063. EXAMPLES:
  1064.  
  1065.       date      BUSINESS JULIAN DATE
  1066.   -----------   --------------------
  1067.   Jan  5, 1992  92005
  1068.   Jan  5, 1993  93005
  1069.   Dec 31, 1993  93365  [Dec 31 is 365th day of year 1993]
  1070.   Dec 31, 1996  96366  [Dec 31 is 366th day, because 1996 is a leap year]
  1071.  
  1072. -----------------------------------------------------------------------
  1073. NOTE:   * JJJ can be 1 - 4 digits
  1074.         * may include a prefix of a plus or minus ( + or - ) sign
  1075. -----------------------------------------------------------------------
  1076.  
  1077. FORMAT      EXAMPLES      DISCUSSION
  1078. ------      ---------     -----------------------------
  1079. ccyyjjj     1992003       Third day of 1992, i.e. Jan 3, 1992
  1080.             19923         Third day of 1992
  1081.             tttt003       Third day of this year
  1082.             tttt3         Third day of this year
  1083.  
  1084.   yyjjj       92003       Third day of 1992
  1085.               923         Third day of 1992
  1086.               tt003       Third day of this year
  1087.               tt3         Third day of this year
  1088.               01003       Third day of 2001           See
  1089.                           FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1090.  
  1091. NOTE THAT FDATE WILL ACCEPT "JJJ" OF LESS THAN 1 & MORE THAN 366.
  1092. -----------------------------------------------------------------
  1093.  
  1094.   yyjjj       tt1000      the 1000th day from beginning of this year
  1095.               tt0         last day of last year
  1096.               tt-1        next-to-last day of last year
  1097.  
  1098. FDATE /Ff /Iccyyjjj /Od1 /A1992-1  produces... Monday December 30, 1991
  1099. FDATE /Ff /Iccyyjjj /Od1 /A19920   produces... Tuesday December 31, 1991
  1100. FDATE /Ff /Iccyyjjj /Od1 /A1992+1  produces... Wednesday January 1, 1992
  1101.  
  1102. FDATE /Ff /Iccyyjjj /Od1 /A1992366 produces... Thursday December 31, 1992
  1103. FDATE /Ff /Iccyyjjj /Od1 /A1992367 produces... Friday January 1, 1993
  1104.  
  1105. This feature allows limited date arithmetic with ordinary business
  1106. Julian days.  For example, 90 days from tt300 can be shown by:
  1107.  
  1108.                   FDATE /Ff /Iyyjjj /Att390
  1109.  
  1110. GETTING DATE/TIME A FILE WAS CREATED
  1111. ====================================
  1112.  
  1113. FORMAT      EXAMPLES      DISCUSSION
  1114. ------      ---------     -----------------------------
  1115. f           MYFILE.1      Input format F (file) tells Fdate that
  1116.                           /A and /B will specify filenames, and that
  1117.                           Fdate should pick up the input date and time
  1118.                           from the date/time stamp on a file.
  1119.  
  1120.      Note that if you specify /If, then both /A and /B will be interpreted
  1121.      as filenames.
  1122.  
  1123.      It is not possible to put a filename in /A and a date literal in /B,
  1124.      and then use the "comp" or "dif" function to compare them.  You must
  1125.      first extract the file's date into an environment variable, and then
  1126.      compare that environment variable to the date literal.
  1127.  
  1128.           The only exception to this rule is the pseudodate "t" (i.e. /At
  1129.           or /Bt) which will pick up the current date and time from the
  1130.           system clock.  This feature will allow you, for example, to
  1131.           compare the date of a file to today's date (see EXAMPLES).
  1132.  
  1133.      A filename may (but need not) be fully qualified: i.e. "MYFILE.1" and
  1134.      "C:\DBASE\WORKDIR\MYFILE.1" are both acceptable.
  1135.  
  1136.      A filename may contain wildcards.  If it does, the date/time stamp
  1137.      will be retrieved from the first file that FDATE finds that meets the
  1138.      filespec.  Giving FDATE a filespec containing a wildcard is pretty
  1139.      useless, but FDATE will not reject it.
  1140.  
  1141. OUTPUT DATE FORMATS
  1142. ===================
  1143.  
  1144. FORMAT        EXAMPLES      DISCUSSION
  1145. ------        ---------     -----------------------------
  1146. dd-mn3-yy     08-Feb-92     CompuServe-style date
  1147.   yy            93          2-digit year number
  1148. ccyy          1993          4-digit year number (includes century)
  1149. ccyymm        199302        useful for triggering monthly processing
  1150. ccyymmdd      19930208      useful for putting current date in filename
  1151.   yymmdd        908208      useful for putting current date in filename
  1152.     mmdd          0208
  1153.       mm            02      2-digit month number
  1154.       zm             2      month number, no leading zeros
  1155.       dd            08      2-digit day-of-month number
  1156.       zd             8      day-of-month number, no leading zeros
  1157.  
  1158. In the following formats, months precede days (American style)
  1159. ------------------------------------------------------------------
  1160. mm/dd/ccyy    02/08/1993
  1161. mm-dd-ccyy    02-08-1993
  1162. mm.dd.ccyy    02.08.1993    British-style dates
  1163.  
  1164. zm/zd/ccyy     2/8/1993     no leading zeros in day or month
  1165. zm-zd-ccyy     2-8-1993     no leading zeros in day or month
  1166. zm.zd.ccyy     2.8.1993     British-style dates
  1167.  
  1168. mm/dd/yy      02/08/92
  1169. mm-dd-yy      02-08-92
  1170. mm.dd.yy      02.08.92      British-style dates
  1171.  
  1172. zm/zd/yy       2/8/92       no leading zeros in day or month
  1173. zm-zd-yy       2-8-92       no leading zeros in day or month
  1174. zm.zd.yy       2.8.92       no leading zeros in day or month
  1175.  
  1176.  
  1177.  
  1178. In the following formats, days precede months  (European style)
  1179. ------------------------------------------------------------------
  1180.  
  1181. ddmmccyy      02081993
  1182. ddmmyy        020893
  1183.  
  1184. dd/mm/ccyy    02/08/1993
  1185. dd-mm-ccyy    02-08-1993
  1186. dd.mm.ccyy    02.08.1993    British-style dates
  1187.  
  1188. zd/zm/ccyy     2/8/1993     no leading zeros in day or month
  1189. zd-zm-ccyy     2-8-1993     no leading zeros in day or month
  1190. zd.zm.ccyy     2.8.1993     British-style dates
  1191.  
  1192. dd/mm/yy      02/08/93
  1193. dd-mm-yy      02-08-93
  1194. dd.mm.yy      02.08.93      British-style dates
  1195.  
  1196. zd/zm/yy       2/8/93       no leading zeros in day or month
  1197. zd-zm-yy       2-8-93       no leading zeros in day or month
  1198. zd.zm.yy       2.8.93       British-style dates
  1199.  
  1200. DAY-OF-WEEK AND MONTH OUTPUT FORMATS
  1201. ====================================
  1202.  
  1203. dow#           5            Sunday=1, Monday=2 .... Saturday=7.
  1204.  
  1205. dow            Thursday     name of day of week
  1206.                jeudi        if /Lfr specified
  1207.                Donnerstag   if /Lgr specified
  1208.  
  1209. dow3           Thu          first 3 characters of name of day of week
  1210.                jeu          if /Lfr specified
  1211.                Don          if /Lgr specified
  1212.  
  1213. mn             February     name of month
  1214.                fevrier      if /Lfr specified
  1215.                Februar      if /Lgr specified
  1216.  
  1217. mn3            Feb          first 3 characters of name of month
  1218.                fev          if /Lfr specified
  1219.                Feb          if /Lgr specified
  1220.  
  1221.  
  1222.  
  1223. MISCELLANEOUS OUTPUT FORMATS
  1224. ============================
  1225.  
  1226. full      9:05 pm on Wednesday February 5, 1992
  1227.           9:05 pm, mercredi le 5 fevrier 1992  [/Lfr specified]
  1228.           9:05 pm, miércoles el 5 de febrero de 1992 [/Lsp specified]
  1229.           Mittwoch, 5. Februar 1992, 21:05     [/Lgr specified]
  1230.  
  1231. d1        Saturday, February 5, 1992
  1232.           samedi le 5 fevrier 1992      [/Lfr specified]
  1233.           Mittwoch, 5. Februar 1992     [/Lgr specified]
  1234.  
  1235. ddmn3yy   05Feb92
  1236.  
  1237. xxx       2CP  (...Dec 25, 1992)
  1238.           This format represents dates for the years 1990-2024 in 3
  1239.           characters of "extended hex" ("XX") notation.  For more on XX
  1240.           notation, see the discussion of the #2XX function.
  1241.  
  1242.           The first character is the XX representation of the number of
  1243.           years since 1990 (1990 = 0, 1991 = 1, etc.).  If you attempt to
  1244.           output a date outside of the 1990-2024 range in XXX format, Fdate
  1245.           will report an error (i.e. return "ERROR" and errorlevel of 1).
  1246.  
  1247.           The second and third characters contain the XX representation of
  1248.           the month-number and day-of-month-number, respectively.
  1249.  
  1250.           EXAMPLE: "1993 Feb  1"  is represented as  "321"
  1251.           EXAMPLE: "2000 Dec 25"  is represented as  "ACP".
  1252.  
  1253. -----------------------------------------------------------------------
  1254. NOTE that the following formats contain embedded spaces.  Consequently
  1255. they must be enclosed in double quotes. EXAMPLE: /O"mn zd, ccyy".
  1256. -----------------------------------------------------------------------
  1257. "zd mn ccyy"      5 February 1992
  1258. "zd mn, ccyy"     5 February, 1992
  1259. "zd. mn ccyy"     5. February 1992   [German-style date format]
  1260. "zd. mn3 ccyy"    5. Feb 1992        [German-style date format]
  1261. "mn3 dd ccyy"     Feb 05 1992
  1262. "mn3 dd, ccyy"    Feb 05, 1992
  1263. "mn zd, ccyy"     February 5, 1992
  1264.  
  1265.  
  1266.  
  1267. LEAP-YEAR FLAG OUTPUT FORMAT
  1268. ============================
  1269.  
  1270. LY              0     "1" if date occurs in a leapyear, otherwise "0".
  1271.  
  1272.                  365 + this number gives total number of days in the year.
  1273.                   28 + this number gives total number of days in February.
  1274.  
  1275.  
  1276.  
  1277.  
  1278. TIME OUTPUT FORMATS
  1279. ===================
  1280. See also: the section on the /T (parm /A time override) parameter.
  1281.  
  1282. t1            9:05 am
  1283.               9:05 pm
  1284.  
  1285. HH:MM        09:05      24-hour time, hours:minutes
  1286.              21:05
  1287. HHMM         0905
  1288.              2105
  1289.  
  1290. HH:MM:SS     21:05:30   24-hour time, hours:minutes:seconds
  1291. HHMMSS       210530
  1292.  
  1293.  
  1294. BUSINESS JULIAN DATE OUTPUT FORMATS
  1295. ===================================
  1296.  
  1297. These are formats for "business julian" dates: dates expressed as the
  1298. number of days from the beginning of the year, when January 1 is day 1.
  1299.  
  1300. EXAMPLES:
  1301.  
  1302.       DATE      BUSINESS JULIAN DATE
  1303.   -----------   --------------------
  1304.   Jan  5, 1993  93005
  1305.   Dec 31, 1993  93365  [Dec 31 is 365th day of year 1993]
  1306.   Dec 31, 1996  96366  [Dec 31 is 366th day, because 1996 is a leap year]
  1307.  
  1308.  
  1309. FORMAT        EXAMPLES      DISCUSSION
  1310. ------        ---------     -----------------------------
  1311.  
  1312. ccyyjjj       1992027       Jan 27, 1992
  1313.   yyjjj         92027       "Business Julian" date expressed as number
  1314.     jjj           027       of days since January 1 of the same year.
  1315.     zzj            27       Note leading zero suppression in "zzj".
  1316.  
  1317.  
  1318. ABSOLUTE DATE/TIME OUTPUT FORMATS
  1319. =================================
  1320. See also: the section on the /T (parm /A time override) parameter.
  1321.  
  1322.  
  1323. day#           727198       "Absolute date": date expressed as number
  1324.                             of days since January 1, 0001.
  1325.  
  1326. minute#         33088       "Absolute minutes": time expressed as number
  1327.                             of minutes  since midnight, January 1, 1990.
  1328.  
  1329. second#        633088       "Absolute seconds": time expressed as number
  1330.                             of seconds  since midnight, January 1, 1990.
  1331.  
  1332.  
  1333. Running FDATE with /O parameter for an "absolute time" produces a
  1334. number based on the current time of day and the date in the /A parm.
  1335.  
  1336. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1337.        FDATE /Ff /Atoday /Ominute#
  1338. it will produce the absolute minute for January 10, 1992 at 2 pm.
  1339.  
  1340. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1341.        FDATE /Ff /A01-15-1992 /Imm-dd-ccyy  /Ominute#
  1342. it will produce the absolute minute for January 15, 1992 at 2 pm.
  1343.  
  1344.  
  1345. /T: TIME OVERRIDE PARAMETER
  1346. ===============================
  1347.  
  1348. You may override Fdate's use of the current time -- for the /A parameter
  1349. only -- by using the /T parameter.  The /T parameter specifies a time of
  1350. day in the 24-hour format hh:mm:ss (hours:minutes:seconds).  Leading zeros
  1351. in each of the three fields (hh, mm, ss) may be omitted.  The seconds field
  1352. may be omitted; if omitted, it defaults to "00".
  1353.  
  1354. Note that the /T parm overrides the time portion of the /A date, but it
  1355. does NOT override the time portion of the /B date.
  1356.  
  1357. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1358.        FDATE /Ff /A01-15-1992 /Imm-dd-ccyy  /Ominute#  /T5:12
  1359. it will produce the absolute minute for January 15, 1992 at 5:12 am.
  1360.  
  1361. The most frequent and important use of the /T parm is with the format
  1362. function (/Ff) to obtain the "absolute" minute of a specific date and time. 
  1363. Once we have the absolute minutes of two different date/times, we can
  1364. easily obtain the time between them (expressed in days, hours, and minutes)
  1365. by using Fdate's #dif, #idiv, and #mod functions.  (In the EXAMPLES
  1366. section, see the example that contains FORATIME.BAT.)
  1367.  
  1368. It is also possible to use /T in conjunction with the time compare function
  1369. (/Ftcomp).
  1370.  
  1371. @echo ON
  1372. cls
  1373. rem  Since both /A and /B default to the current date and time,
  1374. rem  and since /T parm overrides the time only for the /A parm ...
  1375.  
  1376. rem   ... during daytime hours, this will always return LT
  1377. Fdate /ftcomp /T00:00:00
  1378. rem   ... during daytime hours, this will always return GT
  1379. Fdate /ftcomp /T23:59:59
  1380.  
  1381.  
  1382. HOW TO PUT FDATE OUTPUT INTO AN ENVIRONMENT VARIABLE
  1383. ====================================================
  1384.  
  1385.  
  1386. CALL A BATCH FILE
  1387. =================
  1388.  
  1389.   The most basic way to put FDATE's output into an environment variable,
  1390.   although not the most convenient, is to:
  1391.   *  use the /P (prefix string) feature to create a DOS "SET" statement,
  1392.   *  redirect the output to a batch file, and then
  1393.   *  CALL the batch file.  
  1394.  
  1395.   Since CALL first appeared in DOS 3.3, you will need DOS 3.3 or greater
  1396.   to use this technique.
  1397.  
  1398.        FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET FDATE=" >JUNKTEMP.BAT
  1399.        call JUNKTEMP.BAT
  1400.        del  JUNKTEMP.BAT
  1401.  
  1402.  
  1403.  
  1404. USE AN ENVIRONMENT-MANIPULATION UTILITY
  1405. =======================================
  1406.  
  1407.   There are shareware and public domain utilities that are written
  1408.   specifically to manipulate environment variables, and do that job very
  1409.   well.  FDATE's output can be put into an environment variable by piping
  1410.   it to one of these utilities.  When piping FDATE output to a utility,
  1411.   you can prevent the output from being ECHOed to the screen by
  1412.   redirecting the output to NUL.
  1413.  
  1414.   Of these utilities, I can especially recommend Bob Stephan's GET
  1415.   (because it is very inexpensive and very powerful and flexible) and PC
  1416.   Magazine's STRINGS (free to ZiffNet members).  See the EXAMPLES section
  1417.   for examples of how to use STRINGS and GET to put FDATE's output into an
  1418.   environment variable.
  1419.  
  1420.      As of March 14, 1994, the current version of GET is 2.6.  On
  1421.      CompuServe, use IBMFF to look for GET25.ZIP (which contains version
  1422.      2.5 and the full documentation file) and GET26u.ZIP (the version 2.6
  1423.      update of GET, which contains version 2.6 of GET, but not the full
  1424.      documentation).  Look in CIS:IBMSYS, Library 1, or for GET.ZIP in
  1425.      ZNT:UTILFORUM, lib 16.  GET is also available from the Public Software
  1426.      Library in Houston.
  1427.  
  1428.      As of February 14, 1992, the current version of STRINGS is 1.3. On
  1429.      CompuServe, look for STRING.ZIP in the PC Magazine Utilities Lib of
  1430.      ZNT:UTILFORUM.  STRHYP.ZIP contains good hypertext documentation on
  1431.      STRINGS.
  1432.  
  1433. FDATE'S /V PARAMETER
  1434. ====================
  1435.  
  1436.   Manipulating the environment is an incredibly tricky business.  There
  1437.   are questions of the local versus master environment, the version of DOS
  1438.   you are running, and the environment under which you are running (DOS,
  1439.   Windows, QuarterDeck, Carousel).  In order to keep FDATE focussed on
  1440.   date-related issues, versions of Fdate prior to 6.1 did not attempt to
  1441.   put output directly into an environment variable.  Instead, FDATE's
  1442.   output was written to standard output, that is, it was displayed on the
  1443.   screen. Output could then be redirected to a batch file, or piped to a
  1444.   utility (such as STRINGS or GET), that would put the output into an
  1445.   environment variable.
  1446.  
  1447.   Starting with version 6.1, Fdate supports a /V (environment variable)
  1448.   parameter.  A user can use /V to tell Fdate to put its output directly
  1449.   into an environment variable in the "parent" environment.
  1450.  
  1451.   NOTE that due to the complexities of manipulating the environment, there
  1452.   may be circumstances where /V doesn't work.  These include running FDATE
  1453.   when you have shelled out to DOS from another program, have put the
  1454.   command processor in upper memory (UMB) (see below), are running under
  1455.   Carousel, etc.  In such cases, you may be able to use one of the more
  1456.   basic techniques described above.  For a list of environments in which
  1457.   the /V option has been reported as NOT working, see the next section.
  1458.  
  1459.  
  1460.  
  1461.   /Vevar tells Fdate to put output into an environmental variable whose
  1462.   name is "evar".  For example:
  1463.  
  1464.                 Fdate /Ff /Vdate1
  1465.  
  1466.   will set the environment variable DATE1 to the current date.  If you
  1467.   type SET at the DOS prompt, you should see something like:
  1468.  
  1469.                 DATE1=Friday February 14, 1992
  1470.  
  1471.   If you specify /V without an evar name, the evar name defaults to FDATE.
  1472.  
  1473.      Example :       Fdate /Ff /V
  1474.      produces:       FDATE=Friday February 14, 1992
  1475.  
  1476.   If you do not use /V, Fdate output is written to standard output, i.e.
  1477.   to the screen.
  1478.  
  1479. /V WHEN RUNNING UNDER MICROSOFT WINDOWS
  1480. =======================================
  1481.  
  1482. Starting with FDATE version 8.4 -- thanks to a Turbo Pascal routine from
  1483. the Turbo Professional library (see below) provided by Kim Kokkonen of
  1484. TurboPower Software -- FDATE's /V parameter works even in a Windows DOS
  1485. box, assuming you have enough environment space available.
  1486.  
  1487. Starting with Windows 3.1, Windows reads the SHELL= statement in your
  1488. CONFIG.SYS file and allocates the same amount of environment space to a DOS
  1489. window that you specify there.  I've found that using the SHELL= statement
  1490. to set the environment size to 512 bytes is adequate for all of my needs.
  1491.  
  1492. If you're running Windows 3.0, or earlier, you should upgrade immediately! 
  1493. Until then, always start Windows from a batch file that contains the
  1494. following line, executed BEFORE you start Windows:
  1495.  
  1496.    SET DUMMY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  1497.  
  1498. This will reserve a chunk of environment space that will be copied into the
  1499. environment in the Windows DOS box.  Then, as one of the first statements
  1500. in any batch file that you run under Windows, put
  1501.  
  1502.    SET DUMMY=
  1503.  
  1504. This will free up the environment space used by all those "X"s.  For a good
  1505. treatment of running DOS apps under Windows, including a discussion of the
  1506. environment, I recommend Brian Livingston's WINDOWS 3.1 SECRETS (Ch. 7).
  1507.  
  1508. Turbo Professional: "Highly Recommended"
  1509.  
  1510.   If you do serious Turbo Pascal programming, you should have Turbo
  1511.   Professional or Object Professional library.  Turbo Professional is a
  1512.   library of about 600 routines to do all sorts of useful stuff in Turbo
  1513.   Pascal programs, including:
  1514.  
  1515.     CRT unit emulation, with many added features 
  1516.     Popup windows, virtual screens, and pulldown menu systems.
  1517.     Full screen data entry with formatting and data validation.
  1518.     Complete mouse support, keyboard macros, runtime error recovery.
  1519.     A context sensitive popup help unit.
  1520.     Units for picking from lists of items, including filenames.
  1521.     Easy and reliable ways to make your program memory resident.
  1522.     Interrupt service routine handlers, extended & expanded memory access.
  1523.     BCD arithmetic, including transcendental functions & the Form routine
  1524.     Sorting and searching.
  1525.     Extensive string manipulation & strings longer than 255 characters.
  1526.     Arrays larger than 64K (in RAM, EMS, or paged to disk)
  1527.  
  1528. For more information, call TurboPower at 1-800-333-4160 (9-5 Mountain
  1529. time), send CompuServe mail to 76004,2611, or visit the CompuServe
  1530. TurboPower forum in PCVENB section 6.
  1531.  
  1532. /V WHEN USING 4DOS, NDOS, AND UMB
  1533. =================================
  1534.     --------------------------------------------------------------
  1535.     I have received the following report from Aran Spence about
  1536.     circumstances in which FDATE /V will not set a variable
  1537.     in the master environment.  This report leads me to believe
  1538.     that FDATE /V may also fail to work with MS-DOS if you put
  1539.     the command processor or the environment in Upper Memory.
  1540.                     Note, however, that this behavior has not been tested
  1541.                     with FDATE 8.4's new environment-handling routines.
  1542.     --------------------------------------------------------------
  1543. Steve,
  1544.  
  1545. There are options with 4DOS and NDOS to load the environment and part
  1546. of the command processor into upper memory blocks.  When one of these
  1547. options is used, FDATE /V can't find the environment and produces the
  1548. message:
  1549.  
  1550.    ERROR
  1551.    echo ERROR: Master environment not found
  1552.    pause
  1553.  
  1554. If you have a 4DOS.INI file, it has to contain these lines for FDATE /V
  1555. to work:
  1556.  
  1557.    UMBEnvironment = No
  1558.    UMBLoad = No
  1559.  
  1560. If you have NDOS, the SHELL statement in CONFIG.SYS cannot contain
  1561. any reference to UMB loading via /U (which puts NDOS.COM in UMB), nor
  1562. can it contain a statement of the form:
  1563.                 /E:xxxU
  1564. (which puts xxx bytes of the environment in UMB via the "U" parameter).
  1565.  
  1566. Also, NSTART.BTM or 4START.BTM cannot contain
  1567.          SET NDSHELL=/e+xxxU /U
  1568. in which both U's represent UMB loading of the command processor and the
  1569. environment during secondary shells.
  1570.  
  1571. FDATE'S ERROR HANDLING
  1572. ======================
  1573.  
  1574.    If FDATE detects an error:
  1575.  
  1576.      (1) it will return an errorlevel of 1 (rather than 0), and
  1577.      (2) its output will be 3 lines:
  1578.        * the word ERROR
  1579.        * a DOS batch-file ECHO statement that displays an error message
  1580.        * a DOS batch-file PAUSE statement
  1581.  
  1582.    If Fdate output is displayed directly, or redirected to NUL,
  1583.    you can detect an error by testing the errorlevel for a value of 1.
  1584.  
  1585.    If Fdate output is piped to an environment manipulation utility such
  1586.    as STRINGS or GET, the environment variable will be set to ERROR.
  1587.    Errorlevel will be set by STRINGS/GET, and will probably be 0.
  1588.    In such a case, the only way to detect an error is to test the
  1589.    environment variable for the value ERROR.
  1590.  
  1591.    If FDATE output is redirected to a batch file, which is then
  1592.    CALLed to set an environment variable, the batch file will:
  1593.      * set the environment variable to ERROR,
  1594.      * ECHO the error message, and
  1595.      * pause.
  1596.    You can detect an error by testing errorlevel for the value 1
  1597.    either before or after you CALL the batch file, or 
  1598.    by testing the environment variable for the
  1599.    value ERROR, AFTER you have CALLed the batch file.
  1600.  
  1601. ----------------------------------------------------------------------
  1602.  
  1603.  EXAMPLE:
  1604.    rem use FDATE to check validity of year in parm %1
  1605.    Fdate /Fv /Imm-dd-ccyy /ATT-TT-%1 > nul
  1606.    if errorlevel 1 echo Year parm [%1] is not valid.
  1607.    if errorlevel 1 goto endit
  1608.  
  1609.  EXAMPLE:
  1610.    rem use GET with FDATE, to put FDATE output into into %year%
  1611.    Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy | GET ZE /V%year% >nul
  1612.    if (%year%)==(ERROR) echo Year parm [%1] is not valid.
  1613.    if (%year%)==(ERROR) goto endit
  1614.  
  1615.  EXAMPLE:
  1616.    rem use a batch file with FDATE, to put FDATE output into %year%
  1617.    Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy /P"@set year=">junktemp.bat
  1618.    call junktemp.bat
  1619.    del  junktemp.bat
  1620.    if errorlevel 1 echo Year parm [%1] is not valid.
  1621.    if errorlevel 1 goto endit
  1622.  
  1623. EXAMPLES OF HOW TO USE FDATE
  1624. ============================
  1625.  
  1626. :01 Display Fdate output on screen
  1627. :==================================================================
  1628. FDATE /Ff /At /Od1 /P"Today is "
  1629.  
  1630.  
  1631. :02 Redirect FDATE output to a file
  1632. :==================================================================
  1633. FDATE /Ff /At /Od1 /P"Today is " >FDATE.OUT
  1634.  
  1635.  
  1636. :03 Put FDATE output in an environment variable using a batch file
  1637. :==================================================================
  1638. FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET DATE1=" >JUNKTEMP.BAT
  1639. call JUNKTEMP.BAT
  1640. del  JUNKTEMP.BAT
  1641.  
  1642.  
  1643. :04 Put FDATE output in an environment variable using /V parm
  1644. :==================================================================
  1645. FDATE /Ff /Atoday /O"mn zd, ccyy" /Vdate1
  1646.  
  1647.  
  1648. :05 Put FDATE output in an environment variable using STRINGS
  1649. :==================================================================
  1650. FDATE /Ff /Atoday /O"mn zd, ccyy" |STRINGS date1= ASK >NUL
  1651.  
  1652.  
  1653. :06 Put FDATE output in an environment variable using GET
  1654. :==================================================================
  1655. FDATE /Ff /Atoday /O"mn zd, ccyy" |GET ZE /Vdate1 >NUL
  1656.  
  1657.  
  1658. :07 Change a date from one format into another
  1659. :==================================================================
  1660. FDATE /Ff /Imm-dd-yy /A05-08-92 /Occyymmdd
  1661.  
  1662. :07 Get user input
  1663. :==================================================================
  1664. @echo off
  1665. cls
  1666. echo Enter a date in mm-dd-ccyy format for validation
  1667.  
  1668. :: get user input
  1669. fdate /fget /vUserDate1
  1670.  
  1671. :: validate user input using /Fv (validate function)
  1672. fdate /fv /A%UserDate1% >nul
  1673. if errorlevel 1 echo Invalid date: %UserDate1%
  1674. if errorlevel 1 goto endit
  1675.  
  1676. :: put your batch file processing here ...
  1677. echo Processing date: %UserDate1%
  1678.  
  1679. :endit
  1680. :: cleanup
  1681. set UserDate1=
  1682.  
  1683.  
  1684. :08 Get a user menu selection
  1685. :==================================================================
  1686. @echo off
  1687. :start
  1688. cls
  1689. echo =================================================
  1690. echo             MAKE A MENU SELECTION
  1691. echo =================================================
  1692. echo A menu item A
  1693. echo B menu item B
  1694. echo.
  1695. echo X exit from this program
  1696. echo.
  1697. echo =================================================
  1698. :: get user input in upper case
  1699. FDATE /fgetU /q"Press the letter of your choice, then ENTER > " /vchoice
  1700. echo.
  1701.  
  1702. if (%choice%)==(A) goto Choice_%choice%
  1703. if (%choice%)==(B) goto Choice_%choice%
  1704. if (%choice%)==(X) goto endit
  1705. echo Your choice was not valid: [%choice%]    Please try again.
  1706. pause
  1707. goto Start
  1708.  
  1709. :CHOICE_A
  1710.  echo Put processing for choice %choice% here
  1711.  pause
  1712.  goto Start
  1713.  
  1714. :CHOICE_B
  1715.  echo Put processing for choice %choice% here
  1716.  pause
  1717.  goto Start
  1718.  
  1719. :endit
  1720. set choice=
  1721. cls
  1722.  
  1723.  
  1724. :11 Find the difference in days between two dates
  1725. :==================================================================
  1726. FDATE /Fdif /Imm-dd-ccyy /A%date1% /B%date2% /vdiff
  1727. echo The difference is %diff% days.
  1728.  
  1729.  
  1730. :12 Find the elapsed days/hours/minutes between two date/times.
  1731. :===================================================================
  1732. This batch file was developed in cooperation with Walter Ledge, a sysop for
  1733. CompuServe's CRFORUM.  In addition to being a good example of how to use
  1734. Fdate's /T parm and "#idiv" function, it should be useful for other
  1735. CompuServe sysops who need to submit the same reports that Walt does. 
  1736. Here's Walt's message that started the whole thing.
  1737.  
  1738.   As an assistant sysop on the CRFORUM, I have to submit reports to CIS on
  1739.   the number of messages that are posted on our forum in terms of time per
  1740.   1,000 messages -- i.e., say, I know that 1,000 messages were posted
  1741.   between the hours of 17:05 on July 5 and 3:03 on July 7.  I need to know
  1742.   how many hours and minutes it took for those 1000 messages to be posted. 
  1743.   So I would like some way to use FDATE to calculate the difference
  1744.   between those two times (which, of course, include the dates).
  1745.  
  1746. FORATIM2.BAT, which occurs in the next example, is an improvement of this
  1747. batch file.  FORATIM2.BAT uses the /Fget function, which first appeared in
  1748. Fdate 8.3, to get user input from the terminal, rather than requiring all
  1749. parameters to be entered at the command line as FORATIME.BAT does.
  1750.  
  1751. @echo off
  1752. cls
  1753. :: ------------------------------------------------------
  1754. :: FORATIME.BAT batch file
  1755. ::
  1756. :: FUNCTION
  1757. ::    Calculate the elapsed time (in days and minutes)
  1758. ::    between some "begin" date/time and some "end" date/time
  1759. ::
  1760. :: USAGE
  1761. :: This batch file requires 4 command-line parameters
  1762. ::
  1763. ::       BegDate BegTime EndDate EndTime
  1764. ::
  1765. :: Dates must include full 4-digit for year: mm-dd-ccyy
  1766. :: Times must be in 24-hour format: hh:mm
  1767. ::
  1768. :: EXAMPLE
  1769. :: To calculate the elapsed time between
  1770. ::     February 28, 1993 @  8:11 pm  and
  1771. ::     March     2, 1993 @  9:15 am
  1772. ::     (note that 8:11 pm is 20:11 in 24-hour time format)
  1773. ::
  1774. :: enter at the DOS prompt:
  1775. ::
  1776. ::     FORATIME 2-28-1993 20:11 3-2-1993 9:15
  1777. ::
  1778. :: ------------------------------------------------------
  1779. :
  1780. set BEGdate=%1
  1781. set BEGtime=%2
  1782. set ENDdate=%3
  1783. set ENDtime=%4
  1784.  
  1785. ECHO Starting FORATIME calculations.
  1786. ECHO      BEGIN date/time parms are:  %1   %2
  1787. ECHO      END   date/time parms are:  %3   %4
  1788. ECHO.
  1789. ECHO Validating BEGIN date/time parameters...
  1790. fdate /fv /A%BEGdate% /T%BEGtime% >nul
  1791. if errorlevel 1 goto endit
  1792.  
  1793. :: get absolute minute of start date/time.
  1794. fdate /ff /ominute# /A%BEGdate% /T%BEGtime% /VABStime1
  1795. if errorlevel 1 goto endit
  1796. fdate /ff /ofull    /A%BEGdate% /T%BEGtime% /Vfull1
  1797.  
  1798. ECHO Validating  END  date/time parameters...
  1799. fdate /fv /A%ENDdate% /T%ENDtime% >nul
  1800. if errorlevel 1 goto endit
  1801.  
  1802. :: get absolute minute of end date/time.
  1803. fdate /ff /ominute# /A%ENDdate% /T%ENDtime% /VABStime2
  1804. if errorlevel 1 goto endit
  1805. fdate /ff /ofull    /A%ENDdate% /T%ENDtime% /Vfull2
  1806.  
  1807. ECHO Calculating elapsed time...
  1808. :: calculate the difference between ABStime1 and ABStime2
  1809. fdate /f#dif  /A%ABStime1% /B%ABStime2% /VMinutes
  1810.  
  1811. :: calculate the number of hours in it took
  1812. fdate /f#Idiv  /A%minutes% /B60  /VHours
  1813.  
  1814. :: calculate the number of extra minutes it took
  1815. fdate /f#mod   /A%minutes% /B60  /VMins
  1816.  
  1817. echo.
  1818. echo      Between %full1%
  1819. echo          and %full2%
  1820. echo.
  1821. echo      Elapsed time was: %hours% hours and %mins% minutes
  1822.  
  1823. fdate /f#Idiv /A%minutes% /B1440 /Vday1
  1824. fdate /f#mod  /A%minutes% /B1440 /Vmin1
  1825. fdate /f#Idiv /A%min1%    /B60   /Vhour1
  1826. fdate /f#mod  /A%min1%    /B60   /Vmin2
  1827. echo      Elapsed time was: %day1% day(s) %hour1% hour(s) and %min2%
  1828. minute(s).
  1829. echo.
  1830. echo.
  1831.  
  1832. : :: cleanup
  1833. set ENDdate=
  1834. set BEGdate=
  1835. set BEGtime=
  1836. set ENDtime=
  1837. set full1=
  1838. set full2=
  1839. set minutes=
  1840. set ABStime1=
  1841. set ABStime2=
  1842. set day1=
  1843. set hour1=
  1844. set min1=
  1845. set min2=
  1846. set mins=
  1847. set hours=
  1848. :endit
  1849.  
  1850.  
  1851. :13 FORATIM2.BAT
  1852. :==================================================================
  1853.  
  1854. FORATIM2.BAT, is the same as FORATIME.BAT in the previous example, except
  1855. that it uses the /Fget function, which first appeared in Fdate 8.3, to get
  1856. user input from the terminal, rather than requiring all parameters to be
  1857. entered at the command line.
  1858.  
  1859. @echo off
  1860. cls
  1861. :: ------------------------------------------------------
  1862. :: FORATIM2.BAT batch file
  1863. ::
  1864. :: FUNCTION
  1865. ::    Calculate the elapsed time (in days and minutes)
  1866. ::    between some "begin" date/time and some "end" date/time
  1867. ::
  1868. :: ------------------------------------------------------
  1869. ECHO --------------------------------------------------------------
  1870. ECHO     Calculate elapsed time between two date/times
  1871. ECHO --------------------------------------------------------------
  1872.  
  1873. :BegDate
  1874. Fdate /Fget /VBEGdate /Q"Enter BEGIN DATE (mm-dd-ccyy): "
  1875. :BegTime
  1876. Fdate /Fget /VBEGtime /Q"Enter BEGIN TIME (hh:mm).....: "
  1877.  
  1878. :: validate date & time
  1879. fdate /fv /A%BEGdate% /T%BEGtime% >nul
  1880. if errorlevel 1 echo Invalid date/time
  1881. if errorlevel 1 goto BegDate
  1882.  
  1883. :: get absolute minute of start date/time.
  1884. fdate /ff /ominute# /A%BEGdate% /T%BEGtime% /VABStime1
  1885. if errorlevel 1 goto BegTime
  1886. fdate /ff /ofull    /A%BEGdate% /T%BEGtime% /Vfull1
  1887.  
  1888. :
  1889. echo.
  1890. :EndDate
  1891. Fdate /Fget /VENDdate /Q"Enter END.. DATE (mm-dd-ccyy): "
  1892. :EndTime
  1893. Fdate /Fget /VENDtime /Q"Enter END.. TIME (hh:mm).....: "
  1894.  
  1895. :: validate date & time
  1896. fdate /fv /A%ENDdate% /T%ENDtime% >nul
  1897. if errorlevel 1 echo Invalid date/time
  1898. if errorlevel 1 goto EndDate
  1899.  
  1900. :: get absolute minute of end date/time.
  1901. fdate /ff /ominute# /A%ENDdate% /T%ENDtime% /VABStime2
  1902. if errorlevel 1 goto EndTime
  1903. fdate /ff /ofull    /A%ENDdate% /T%ENDtime% /Vfull2
  1904.  
  1905. echo.
  1906. ECHO Calculating elapsed time...
  1907. :: calculate the difference between ABStime1 and ABStime2
  1908. fdate /f#dif  /A%ABStime1% /B%ABStime2% /VMinutes
  1909.  
  1910. :: calculate the number of hours in it took
  1911. fdate /f#Idiv  /A%minutes% /B60  /VHours
  1912.  
  1913. :: calculate the number of extra minutes it took
  1914. fdate /f#mod   /A%minutes% /B60  /VMins
  1915.  
  1916. echo.
  1917. echo   Between %full1%
  1918. echo       and %full2%
  1919. echo.
  1920. echo   Elapsed time was:
  1921. echo           %hours% hours and %mins% minutes
  1922.  
  1923. fdate /f#Idiv /A%minutes% /B1440 /Vday1
  1924. fdate /f#mod  /A%minutes% /B1440 /Vmin1
  1925. fdate /f#Idiv /A%min1%    /B60   /Vhour1
  1926. fdate /f#mod  /A%min1%    /B60   /Vmin2
  1927. echo   or
  1928. echo         %day1% day(s) %hour1% hour(s) and %min2% minute(s).
  1929. echo.
  1930. echo.
  1931. :
  1932. :: cleanup
  1933. set ENDdate=
  1934. set BEGdate=
  1935. set BEGtime=
  1936. set ENDtime=
  1937. set full1=
  1938. set full2=
  1939. set minutes=
  1940. set ABStime1=
  1941. set ABStime2=
  1942. set day1=
  1943. set hour1=
  1944. set min1=
  1945. set min2=
  1946. set mins=
  1947. set hours=
  1948. :endit
  1949.  
  1950. :14 Time the execution of a piece of software
  1951. :==================================================================
  1952. COMMENT
  1953.   This example was developed before the addition of the #div and #idiv
  1954.   functions to Fdate, so the run time (in minutes) is not calculated by
  1955.   dividing the run time (in seconds) by 60, as it now could be.
  1956.  
  1957. @echo off
  1958. cls
  1959. ECHO The demo will run for 1 - 60 seconds.
  1960. echo.
  1961. ECHO ─────────────────────────────────────────────────────────────────────
  1962. ECHO CALCULATE HOW LONG IT TOOK TO RUN A PROGRAM (in seconds and minutes)
  1963. echo.
  1964. echo If you leave long batch files to run overnight, this technique can
  1965. echo be used to record how long each program in the batch file ran.
  1966. echo.
  1967. echo The technique for setting the values of environment variables in this
  1968. echo part of the demo uses temporary batch files and CALL statements.
  1969. echo If you have a program such as GET or STRINGS, you can use it instead.
  1970. ECHO ──────────────────────────────────────────────────────────────────────
  1971. echo.
  1972. PAUSE
  1973. cls
  1974.  
  1975. FDATE /Ff /At /Ohh:mm:ss /P"TESTPGM simulated execution begins at "
  1976.  
  1977. REM  GET PROGRAM BEGIN TIME, IN MINUTES
  1978. @set BegM=
  1979. @set EndM=
  1980. @set RunM=
  1981. FDATE /Ff /At /Ominute# /P"SET BegM=" >FDATJUNK.BAT
  1982. CALL FDATJUNK.BAT
  1983.  
  1984. REM  GET PROGRAM BEGIN TIME, IN SECONDS
  1985. set BegS=
  1986. set EndS=
  1987. set RunS=
  1988. FDATE /Ff /At /Osecond# /P"SET BegS=" >FDATJUNK.BAT
  1989. CALL FDATJUNK.BAT
  1990.  
  1991. rem ───────────────────────────────────────────────────────────────
  1992. rem [simulate execution of a program: loop for a minute or less]
  1993. rem [In a real batch file, you would put your program statements here]
  1994. rem ───────────────────────────────────────────────────────────────
  1995. :BegLoop
  1996.    FDATE /Ff /At /Osecond# /P"SET EndS=" >FDATJUNK.BAT
  1997.    CALL FDATJUNK.BAT
  1998.    FDATE /Ff /At /Ominute# /P"SET EndM=" >FDATJUNK.BAT
  1999.    CALL FDATJUNK.BAT
  2000.  
  2001.    rem  calculate run time (difference between start time and end time)
  2002.    FDATE /F#dif /A%EndM% /B%BegM% /P"SET RunM=" > FDATJUNK.BAT
  2003.    CALL FDATJUNK.BAT
  2004.  
  2005.    rem  calculate run time (difference between start time and end time)
  2006.    FDATE /F#dif /A%EndS% /B%BegS% /P"SET RunS=" > FDATJUNK.BAT
  2007.    CALL FDATJUNK.BAT
  2008.    echo      TESTPGM running, elapsed time: %RunS% seconds
  2009.  
  2010.    if (%RunM%)==()  goto EndLoop
  2011.    if (%RunM%)==(0) goto BegLoop
  2012. :EndLoop
  2013. rem ───────────────────────────────────────────────────────────────
  2014.  
  2015. REM  GET PROGRAM END TIME IN SECONDS
  2016. FDATE /Ff /At /Osecond# /P"SET EndS=" > FDATJUNK.BAT
  2017. CALL FDATJUNK.BAT
  2018.  
  2019. REM  GET PROGRAM END TIME IN MINUTES
  2020. FDATE /Ff /At /Ominute# /P"SET EndM=" > FDATJUNK.BAT
  2021. CALL FDATJUNK.BAT
  2022.  
  2023. FDATE /Ff /At /Ohh:mm:ss /P"TESTPGM simulated execution ends at "
  2024. echo.
  2025.  
  2026. echo TESTPGM: Program end   time (Absolute seconds): %EndS%
  2027. echo TESTPGM: Program begin time (Absolute seconds): %BegS%
  2028. rem  calculate run time (difference between start time and end time)
  2029. FDATE /F#dif /A%EndS% /B%BegS% /P"TESTPGM: Run time in seconds= "
  2030. set BegS=
  2031. set EndS=
  2032.  
  2033. echo.
  2034. echo TESTPGM: Program end   time (Absolute minutes): %EndM%
  2035. echo TESTPGM: Program begin time (Absolute minutes): %BegM%
  2036. rem  calculate run time (difference between start time and end time)
  2037. FDATE /F#dif /A%EndM% /B%BegM% /P"TESTPGM: Run time in minutes= "
  2038. DEL  FDATJUNK.BAT
  2039. set BegM=
  2040. set EndM=
  2041. set RunM=
  2042. set RunS=
  2043.  
  2044. :15 Find calendar date corresponding to a "business Julian" date
  2045. :==================================================================
  2046. rem business julian date is 1992:045.  Note input format CCYYjjj
  2047. FDATE /Ff /A1992045  /Iccyyjjj  /Od1
  2048.  
  2049. rem You don't need to left-zero-fill the day
  2050. FDATE /Ff /A199245  /Iccyyjjj  /Od1
  2051.  
  2052. rem You can assume the century, if you specify the YYjjj input format
  2053. FDATE /Ff /A9245  /Iyyjjj  /Od1
  2054.  
  2055.  
  2056. :16 Set your PC's date to a business julian date
  2057. :==================================================================
  2058. @echo off
  2059. goto enddoc
  2060. ---------------------------------------------------------------------
  2061. JDATE.BAT
  2062. This batch file was created by Aran Spence [CIS: 70162,3044].  Its function
  2063. is to emulate the DOS DATE command, but to allow the user to set the date
  2064. using a business julian date format (yyjjj) instead of mm-dd-yy.
  2065.  
  2066. Note the format is YYjjj. This is the BUSINESS julian date: a date
  2067. expressed as the number of days from the beginning of the year, when
  2068. January 1 is day 1.
  2069.  
  2070.            date      BUSINESS julian date
  2071.        -----------   --------------------
  2072.        Jan 5, 1992       92005
  2073.        Jan 5, 1993       93005
  2074.        Dec 31, 1993      93365  [Dec 31 is 365th day of year 1993]
  2075.  
  2076. As Aran originally wrote it, the user-prompt was virtually identical to
  2077. that of the DATE command.  I have modified his original version, so it
  2078. now looks less like the DATE command but displays a bit more
  2079. information, and so it can operate from the command line even if the
  2080. user does not have GET.
  2081.  
  2082. If the user enters a business julian date as a command-line
  2083. parameter, JDATE resets the date to that julian date.
  2084.              EXAMPLE:  JDATE 92005
  2085. If there is no input parameter, GET is used to prompt the user for a
  2086. date.  It is possible to use JDATE even if you don't have GET by
  2087. operating only from the command line, or by substituting some other
  2088. utility (such as STRINGS) for GET.
  2089.  
  2090. Note that the user must enter both of the year digits (yy),
  2091. but may enter an abbreviated set of day digits (jjj).  That is,
  2092. for julian day 92005, the user is permitted to enter 925.
  2093.  
  2094. One handy use for JDATE is simply to find out what the current
  2095. business julian date is.
  2096. ---------------------------------------------------------------------
  2097. :enddoc
  2098.  
  2099. SET NewJD=%1
  2100. if not (%NewJD%)==() goto GotDate
  2101.  
  2102. :ShowDate
  2103. Fdate /Ff /Od1    /P"Current Gregorian date: "
  2104. Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
  2105.  
  2106. :GetDate
  2107. GET S "Enter new date (yyddd): " /VNewJD /L
  2108. if (%NewJD%)==() goto endit
  2109.  
  2110. :GotDate
  2111. Fdate /Ff /A%NewJD% /Omm-dd-yy /Iyyjjj /P"@DATE " > JUNKTEMP.BAT
  2112. if errorlevel 1 if exist JUNKTEMP.BAT del JUNKTEMP.BAT
  2113. if errorlevel 1 echo Invalid date "%NewJD%"
  2114. if errorlevel 1 goto GetDate
  2115.  
  2116. rem  reset the date by calling JUNKTEMP.BAT
  2117. call JUNKTEMP.BAT
  2118. del  JUNKTEMP.BAT
  2119.  
  2120. echo SYSTEM DATE HAS BEEN RESET
  2121. Fdate /Ff /Od1    /P"Current Gregorian date: "
  2122. Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
  2123.  
  2124. :endit
  2125. SET NewJD=
  2126. echo.
  2127.  
  2128.  
  2129. :18 Determine if parm %1 contains a valid date
  2130. :==================================================================
  2131. COMMENT
  2132.   Note that we throw away the FDATE output by redirecting it to NUL.  All
  2133.   we really want here is the errorlevel, which tells us whether or not the
  2134.   string in %1 is a valid year.
  2135.  
  2136. Fdate /Fv /Imm-dd-ccyy /A%1  >nul
  2137. if errorlevel 1 echo Parm 1 was not a valid date: %1
  2138. if errorlevel 1 goto endit
  2139.  
  2140. :
  2141. : Put the body of your batch file here.
  2142. :
  2143.  
  2144. :endit
  2145.  
  2146. :19 "Roll your own" date format 
  2147. :==================================================================
  2148. echo Display date in custom-made format: yymn3dd
  2149. Fdate /Ff /Oyy              /V
  2150. Fdate /Ff /Omn3 /P"%fdate%" /V
  2151. Fdate /Ff /Odd  /P"%fdate%" /V
  2152.  
  2153. echo Today is %fdate%
  2154. set fdate=
  2155.  
  2156.  
  2157.  
  2158. :20 Find the 4th Thursday in November (Thanksgiving)
  2159. :==================================================================
  2160. Fdate /Fw /D5 /N4 /A11-01-%year% /Imm-dd-ccyy /Od1 /P"Thanksgiving: "
  2161.  
  2162.  
  2163.  
  2164. :22 On a date, show what anniversary it is for some event
  2165. :==================================================================
  2166. See HOLIDAYS.BAT demo batch file
  2167.  
  2168.  
  2169.  
  2170. :23 Show a list of holidays in a given year
  2171. :==================================================================
  2172. See HOLIDAYS.BAT demo batch file
  2173.  
  2174.  
  2175. :24 Show a list of Federal holidays in a given year
  2176. :==================================================================
  2177. See HOLIFEDS.BAT demo batch file
  2178.  
  2179.  
  2180. :25 Determine if a year is valid, and evenly divisible by 4
  2181. :==================================================================
  2182.  
  2183. @echo off
  2184. cls
  2185. echo FUNCTION: Accept a year parm (CCYY) as parameter 1.  Determine if
  2186. echo the year is an election or inauguration year in the United States.
  2187. echo ===================================================================
  2188.  
  2189. rem verify %1 is a valid year
  2190. Fdate /Fv /Imm-dd-ccyy /A01-01-%1 >nul
  2191. if errorlevel 1 echo Year parm [%1] is not valid.
  2192. if errorlevel 1 goto endit
  2193.  
  2194. Fdate /Ff /Imm-dd-ccyy /A01-01-%1 /p"@set year=">junktemp.bat
  2195. call junktemp.bat
  2196.  
  2197. Fdate /F#mod /A%1 /B4 /p"@set mod=">junktemp.bat
  2198. call junktemp.bat
  2199. if (%mod%)==(0) echo %1 is an American presidential election year.
  2200. if (%mod%)==(1) echo %1 is an American presidential inauguration year.
  2201. for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an election year.
  2202. for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an inauguration year.
  2203.  
  2204. set mod=
  2205. :endit
  2206. if exist junktemp.bat del  junktemp.bat
  2207.  
  2208.  
  2209.  
  2210.  
  2211. :30 Compare a file's date to today's date
  2212. :==================================================================
  2213. rem Compare today's date to the date on the filename in %1
  2214. Fdate /Fcomp /At /If /B%1 /Vcomp
  2215. if (%comp%)==(EQ) echo %1 was created or updated today
  2216. set comp=
  2217.  
  2218.  
  2219. :31 Compare two files' date/time using COMPARE-FUNCTION ERRORLEVELS
  2220. :==================================================================
  2221. COMMENT
  2222. There are many ways to check errorlevels.  This example shows 
  2223. several of them.
  2224.  
  2225. @echo off
  2226. cls
  2227. SET F1=FDATE.BAT
  2228. SET F2=FDATE.EXE
  2229. fdate /FTcomp /If /A%f1%  /B%F2% /P"%f1% is " /S" %f2%"
  2230.  
  2231. if errorlevel 101 if not errorlevel 103 echo %f1% is LT/EQ %f2%
  2232. if errorlevel 102                       echo %f1% is GT/EQ %f2%
  2233.  
  2234. if errorlevel 101 if not errorlevel 102 echo %f1% is older than %f2%
  2235. if errorlevel 102 if not errorlevel 103 echo %f1% is same age as %f2%
  2236. if errorlevel 103 if not errorlevel 104 echo %f1% is younger than %f2%
  2237.  
  2238. if errorlevel 101 if not errorlevel 103 echo %f1% at least as old as %f2%
  2239. if errorlevel 102                       echo %f1% is no older than %f2%
  2240.  
  2241. if errorlevel 101 if not errorlevel 102 echo errorlevel is 101
  2242. if errorlevel 102 if not errorlevel 103 echo errorlevel is 102
  2243. if errorlevel 103 if not errorlevel 104 echo errorlevel is 103
  2244. SET F1=
  2245. SET F2=
  2246. :endit
  2247.  
  2248.  
  2249.  
  2250. :32 Display a list of all files that were created/updated today. 
  2251. :==================================================================
  2252. @echo off
  2253. if (%1)==(SUBROUTINE) goto %2
  2254.  
  2255. CLS
  2256. ECHO FILES MEETING FILESPEC [%1] THAT WERE CREATED OR UPDATED TODAY
  2257. REM  The batch file calls itself: Its own name is in parm %0
  2258. for %%v in (%1) do  CALL %0 SUBROUTINE CHECKFILE %%v
  2259.  
  2260. set comp=
  2261. goto endit
  2262.  
  2263. :CHECKFILE
  2264. shift
  2265. shift
  2266.  
  2267. rem Compare today's date to the date on the %1 file
  2268. Fdate /Fcomp /If /A%1 /Vcomp  
  2269.  
  2270. rem echo the filename if the file was created/updated today
  2271. if (%comp%)==(EQ) echo %1
  2272. :endit
  2273.  
  2274. :33 Delete files more than X days old (use a batch-file subroutine)
  2275. :==================================================================
  2276. See the COMMENTARY that follows the text of the batch file.
  2277.  
  2278.  
  2279. @echo off
  2280. if (%1)==(SUBROUTINE) goto %2
  2281. cls
  2282.  
  2283. goto EndDoc
  2284. ----------------------------------------------------------------------
  2285. OLDFILES.BAT
  2286. This batch file shows how to do work on files that are older than
  2287. %NumDays%.  The PROCESS! subroutine can be modified to do any kind of
  2288. work you want.
  2289. ----------------------------------------------------------------------
  2290. :EndDoc
  2291.  
  2292. :: set the number of days in the past.   if this value is not passed
  2293. :: in via parameter %1, it defaults to 3 days
  2294. set NumDays=%1
  2295. if (%NumDays%)==() SET NumDays=3
  2296.  
  2297.  
  2298. echo ------------------------------------------------------------------
  2299. echo           PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO
  2300. echo ------------------------------------------------------------------
  2301. for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
  2302. echo ------------------------------------------------------------------
  2303. echo           END OF PROCESSING
  2304. echo ------------------------------------------------------------------
  2305.  
  2306. :: CLEANUP
  2307. set NumDays=
  2308. set DaysOld=
  2309. set Comparison=
  2310. GOTO ENDIT
  2311.  
  2312. :
  2313. :PROCESS!
  2314. shift
  2315. shift
  2316.  
  2317. :: get difference in days between filedate and today.
  2318. :: Note that /B parm (which is omitted) defaults to today's date.
  2319. fdate /fdif   /A%1        /IF          /VDaysOld
  2320.  
  2321. :: compare DaysOld to NumDays
  2322. fdate /f#comp /A%DaysOld% /B%NumDays%  /Vcomparison
  2323.  
  2324. :: the following line will DISPLAY THE NAME AND AGE OF
  2325. :: any file for which %DaysOld% is greater than %NumDays%
  2326. :: --------------------------------------------------------------
  2327. if (%comparison%)==(GT) echo %1 is %DaysOld% days old.
  2328.  
  2329. :: EXAMPLE (to activate this routine, remove the REM from column 1)
  2330. :: the following line will COPY TO AN ARCHIVE SUBDIRECTORY
  2331. :: any file for which %DaysOld% is greater than %NumDays%
  2332. :: -----------------------------------------------
  2333. REM if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.*
  2334.  
  2335. :: EXAMPLE (to activate this routine, remove the REM from column 1)
  2336. :: the following line will DELETE
  2337. :: any file for which %DaysOld% is greater than %NumDays%
  2338. :: -----------------------------------------------
  2339. REM if (%comparison%)==(GT) DEL %1
  2340.  
  2341. :: fall through to endit
  2342.  
  2343. :endit
  2344.  
  2345.  ===============================================================
  2346.                         COMMENTARY BEGIN
  2347.  ===============================================================
  2348.  This batch file uses a crude, but effective, technique for giving a
  2349.  batch file the ability to call subroutines.  If you've never seen
  2350.  something like this before, it is sort of mind-blowing.  Here's some
  2351.  commentary on the more important lines involved in the technique.
  2352.  ===============================================================
  2353.  
  2354.  if (%1)==(SUBROUTINE) goto %2
  2355.  
  2356.     COMMENTARY:
  2357.     If the first parameter, %1, is "SUBROUTINE", then the batch file
  2358.     recognizes that it is being called for the purpose of executing
  2359.     one of its own subroutines.  In such a case, it does a GOTO to the
  2360.     start of the requested subroutine.  That is, it goes to the label
  2361.     whose name is in the second parameter.
  2362.  
  2363.     Explicitly specifying the name of the desired subroutine permits
  2364.     permits us to have multiple subroutines in the batch file,
  2365.     each with its own name.  (As it happens, in this batch file
  2366.     we have only one subroutine, named "PROCESS!")
  2367.  
  2368.     If the first parameter is not "SUBROUTINE", then we fall through
  2369.     and begin executing the main routine of the batch file.  In such a
  2370.     case, the first parameter (%1) may contain a number, indicating
  2371.     the number of days to use in determining which files to delete.
  2372.  
  2373.     Note that this technique will make the batch file malfunction
  2374.     if the user himself ever executes the batch file from the
  2375.     DOS command line with the word "SUBROUTINE" as the first
  2376.     parameter, the word "PROCESS!" as the second parameter, and a
  2377.     third parameter that is missing or not a valid filename.
  2378.     This is so unlikely, however, that it is reasonable
  2379.     to assume that it will never happen.
  2380.  
  2381.  ===============================================================
  2382.  
  2383.  for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
  2384.  
  2385.     COMMENTARY:
  2386.     In a batch file, %0 contains the name by which the batch file was
  2387.     invoked.  We use this fact to allow a batch file to call itself,
  2388.     regardless of what name the user has given to it.
  2389.  
  2390.     The first parameter passed, when the batch file calls
  2391.     itself, is the string "SUBROUTINE".  This string allows the batch
  2392.     file to recognize when it is being called for the purpose of
  2393.     executing one of its own subroutines.
  2394.  
  2395.     The second parameter is the name of the subroutine that we want
  2396.     to call: in this case, "PROCESS!".
  2397.  
  2398.     The third parameter is what we would normally think of as the first
  2399.     parameter to the subroutine.  In this case, when the
  2400.     FOR statement is executed, and the substitution for %%v takes
  2401.     place, it will contain the name of the file to be processed.
  2402.     Note that we could, if we wished, pass additional parameters to
  2403.     the subroutine.  Note also that we can control the files that
  2404.     we process.  We do so via the filemask in the FOR statement.
  2405.     It we used, for example, "*.EXE", then we would process only
  2406.     executable files.
  2407.  
  2408.  ===============================================================
  2409.  
  2410.  GOTO ENDIT
  2411.  
  2412.    COMMENTARY:
  2413.    When the mainline of the batch file is finished executing, we
  2414.    goto the end of the batch file.  We MUST do this GOTO in order
  2415.    to avoid falling through into, and starting to execute, the first
  2416.    of the batch file's subroutines.
  2417.  
  2418.  ===============================================================
  2419.  
  2420.  :PROCESS!
  2421.  shift
  2422.  shift
  2423.  
  2424.    COMMENTARY:
  2425.    Note that when the batch file is called as a subroutine, and the
  2426.    batch file goes to the PROCESS! label, the values of the parms are:
  2427.            %0 = [the name of the batch file]
  2428.            %1 = SUBROUTINE
  2429.            %2 = PROCESS!
  2430.            %3 = [name of the file to be processed]
  2431.  
  2432.     We shift all the parameters to the left twice, to move the
  2433.     parameter(s) into what we think of as the
  2434.     proper places for parameters to the subroutine.
  2435.  
  2436.     After the first SHIFT command:
  2437.            %0 = SUBROUTINE
  2438.            %1 = PROCESS!
  2439.            %2 = [name of the file to be processed]
  2440.  
  2441.     After the second SHIFT command:
  2442.            %0 = PROCESS!
  2443.            %1 = [name of the file to be processed]
  2444.  
  2445.     Now %1 contains what we think of as the proper parameter(s)
  2446.     to the subroutine.  In this case, %1 contains the filename that
  2447.     we want the subroutine to process.
  2448.  
  2449.     At the end of every subroutine, there should be a GOTO ENDIT,
  2450.     which causes the batch file to go to its own end, and then
  2451.     end and return control to the statement in the program which called
  2452.     it.  (This is, of course, the CALL statement embedded in the
  2453.     FOR statement.)
  2454.  
  2455.     We can optimize the batch file a little by omitting the "goto endit"
  2456.     at the end of the last subroutine.  Instead, we simply allow the
  2457.     last subroutine to fall through to the end of the batch file.
  2458.  
  2459.  ===============================================================
  2460.                          COMMENTARY END
  2461.  ===============================================================
  2462.  
  2463. :34 Loop through an array of environment variables
  2464. :======================================================================
  2465. @echo off
  2466. cls
  2467. SET pct=%%%
  2468. SET prefix=Address
  2469.  
  2470. ECHO LOADING AN ARRAY
  2471. SET subscript=1
  2472. SET %prefix%.%subscript%=Stephen Ferg
  2473. SET subscript=2
  2474. SET %prefix%.%subscript%=5113 N. 8th Road
  2475. SET subscript=3
  2476. SET %prefix%.%subscript%=Arlington, VA 22205
  2477.  
  2478. ECHO UNLOADING AND DISPLAYING THE ARRAY
  2479. SET subscript=1
  2480. :LoopTop
  2481. REM do while subscript less than/equal 3
  2482. if %subscript%==4 goto LoopEnd
  2483.  
  2484.    REM put value of subscripted variable into tempvar
  2485.    ECHO SET tempvar=%pct%%prefix%.%subscript%%pct%>JUNKTEMP.BAT
  2486.    CALL JUNKTEMP.BAT
  2487.  
  2488.    REM display value of subscripted variable
  2489.    ECHO %prefix%.%subscript% is: %tempvar%
  2490.  
  2491.    REM delete subscripted variable
  2492.    SET %prefix%.%subscript%=
  2493.  
  2494.    REM increment the loop variable
  2495.    Fdate /F#add /A%subscript% /B1 /Vsubscript
  2496.    goto LoopTop
  2497. :LoopEnd
  2498.  
  2499. SET pct=
  2500. SET tempvar=
  2501. SET prefix=
  2502. SET subscript=
  2503. DEL JUNKTEMP.BAT
  2504.  
  2505. :44 Do something on the last day (or last Friday) of the month
  2506. :==================================================================
  2507. COMMENT
  2508. We often need batch files that do some special task on the last day of the
  2509. month: run a backup job, display a reminder message, etc.  This example
  2510. batch file, LASTDAY.BAT, simply displays a message -- you can modify it to
  2511. do whatever it is that YOU want to do.
  2512.  
  2513. If you plan to run LASTDAY.BAT at work, and you work Monday through Friday,
  2514. then checking for the last day of the month would be a poor strategy --
  2515. after you leave work on a Friday, the last day of the month might occur on
  2516. the following Saturday or Sunday.   So I've included a check to see if the
  2517. Friday is the last working day of the month.  If you don't want that
  2518. functionality, deleting the lines between the first and last occurrence of
  2519. the string "EndCheck" will remove it.
  2520. =======================================================================
  2521.  @echo off
  2522.  REM ---------------------------------------------------------------
  2523.  REM check to see if today is the last day of the month
  2524.  REM ---------------------------------------------------------------
  2525.  REM get today's month
  2526.  fdate /ff        /omm /vmmtoday
  2527.  
  2528.  REM get tomorrow's month
  2529.  fdate /fadd /n1 /omm  /vmmtomorrow
  2530.  
  2531.  REM if tomorrow occurs in a different month,
  2532.  REM then today is the last day of this month
  2533.  if not (%mmtoday%)==(%mmtomorrow%) echo LAST DAY OF THE MONTH
  2534.  if not (%mmtoday%)==(%mmtomorrow%) goto EndCheck
  2535.  
  2536.  REM -------------------------------------------------------------
  2537.  REM check to see if today is the last Friday of the month
  2538.  REM -------------------------------------------------------------
  2539.  rem get today's day of the week, to see if it is Friday
  2540.  fdate /ff /odow3 /vdow3
  2541.  if not (%dow3%)==(Fri) goto EndCheck
  2542.  
  2543.  REM today is Friday.  Get next Monday's month
  2544.  fdate /fadd /n3 /omm  /vmmMonday
  2545.  
  2546.  REM if next Monday occurs in a different month,
  2547.  REM then today is the last Friday of this month
  2548.  if not (%mmtoday%)==(%mmMonday%) echo LAST WORKING DAY OF THE MONTH
  2549.  
  2550.  :EndCheck
  2551.  
  2552.  REM cleanup
  2553.  set dow3=
  2554.  set mmtoday=
  2555.  set mmtomorrow=
  2556.  set mmMonday=
  2557.  
  2558. :45 Get information about the month prior to the current month
  2559. :==================================================================
  2560. COMMENT
  2561. When running a monthly backup job at the beginning of the month, one often
  2562. needs to identify the previous month, or the last day of the previous
  2563. month.  Here's how to use Fdate to obtain that sort of information. 
  2564. Basically, we subtract one day from the first day of the current month,
  2565. giving us the last day of the previous month.
  2566. =======================================================================
  2567. @echo off
  2568. cls
  2569. : The simplest way to get information about last month is to subtract
  2570. : 1 day from the first day of this month ...
  2571.  
  2572. fdate /fsub /n1 /att-01-tttt /omm   /p"Last month was.................: "
  2573. fdate /fsub /n1 /att-01-tttt /occyy /p"Last month occurred in the year: "
  2574. fdate /fsub /n1 /att-01-tttt /odd   /p"The last day of last month was : "
  2575. fdate /fsub /n1 /att-01-tttt /od1   /p"The last day of last month was : "
  2576.  
  2577. :50 Represent a date in 3 bytes of "extended hex" notation
  2578. :==================================================================
  2579.  
  2580. rem produce today's date as 3 bytes
  2581. fdate /ff /oxxx 
  2582.  
  2583. rem produce yesterday's date in xxx format
  2584. fdate /fsub /N1 /oxxx
  2585.  
  2586.  
  2587.  
  2588.  
  2589. :51 Represent a date in a short (4-byte) format (technique #1)
  2590. :==================================================================
  2591. COMMENT
  2592. A common use of Fdate is to format today's date and use it to rename a file
  2593. (typically a log file of some sort).  You may wish to store the date
  2594. information in as few characters as possible, in order to maximize the
  2595. number of other characters in the filename that you can use to store other
  2596. information.
  2597.  
  2598. In this example, and the next one, I illustrate two ways to store a date in
  2599. 4 bytes.
  2600.  
  2601.  
  2602. The simplest way is to represent today's date as a 4-digit number.
  2603. To do this, we first pick a base date:  I'll use January 1, 1990.
  2604. Then it is a simple matter to calculate the number of days between today
  2605. and the base date:
  2606.  
  2607.            FDATE /Fdif /at /b01-01-1990 
  2608.  
  2609. Starting in 1993, this will always generate a 4-digit number, and will
  2610. continue to do so for 20 years, until approximately the year 2003.  Dates
  2611. before 1993 may produce 1-, 2-, or 3-digit numbers, and dates after 2003
  2612. will begin to produce 5-digit numbers.  But this technique will work quite
  2613. nicely for most ordinary purposes for the next 20 years.  
  2614.  
  2615. If you're still using DOS in the year 2003, then in 2003 you can switch to
  2616. using January 1, 2000 as your base date and function quite nicely for the
  2617. next 20 years after that.
  2618.  
  2619. :52 Represent a date in a short (4-byte) format (technique #2)
  2620. :==================================================================
  2621. @echo off
  2622. cls
  2623. goto end-doc
  2624. ------------------------------------------------------------------
  2625. This batch file shows how to use Fdate's #2XX function to
  2626. obtain and represent today's date in 4 characters, YYMD, where:
  2627.  
  2628.   YY is the year (e.g. "93" for 1993)
  2629.    M is the month in extended hexadecimal (XX) notation
  2630.    D is the day-of-the-month in extended hexadecimal (XX) notation
  2631.  
  2632. You can also use Fdate's "XXX" output format to represent dates between
  2633. 1990 and 2024 in 3 bytes of extended hex notation.
  2634. ------------------------------------------------------------------
  2635. :end-doc
  2636.  
  2637. REM OBTAIN 1-CHARACTER REPRESENTATION FOR THE MONTH
  2638. Fdate /ff    /Omm   /Vmm
  2639. Fdate /f#2xx /A%mm% /Vmm
  2640. echo XX representation of this month's number      is %mm%
  2641.  
  2642. REM OBTAIN 1-CHARACTER REPRESENTATION FOR THE DAY
  2643. Fdate /ff    /Odd   /Vdd
  2644. Fdate /f#2xx /A%dd% /Vdd
  2645. echo XX representation of today's day of the month is %dd%
  2646.  
  2647. REM CONCATENATE THEM TO THE 2-CHARACTER REPRESENTATION FOR THE YEAR
  2648. Fdate /Ff /Oyy /S%mm%%dd% /Vdate
  2649. echo XX representation of today's full date        is %date%
  2650.  
  2651. REM CLEANUP
  2652. set mm=
  2653. set dd=
  2654. set date=
  2655. :endit
  2656.  
  2657.  
  2658. :54 Customize Fdate for a language of your choice
  2659. :==================================================================
  2660. @echo off
  2661. cls
  2662. goto end-doc
  2663. ------------------------------------------------------------------
  2664. You can use Fdate with a customized batch file to obtain the names of
  2665. the days of the week and the months in a language of your choice.  Or
  2666. you could use it to obtain names in uppercase, or the first 5
  2667. characters of the names (rather than the first three), or some other
  2668. customized formatting of your choice.)
  2669.  
  2670. I've invented a language called Fergian, which has its own names for
  2671. the days of the week, and the months.  In the following examples, I
  2672. invoke FERGIAN.BAT to make the translation.  The text of FERGIAN.BAT,
  2673. which does the real work here, is given in the next example.
  2674. ------------------------------------------------------------------
  2675. :end-doc
  2676.  
  2677. fdate /ff /omm /v
  2678. call Fergian mm- result %Fdate%
  2679. echo Month  is          %result%
  2680.  
  2681. fdate /ff  /omm /v
  2682. call Fergian mm3 result %Fdate%
  2683. echo Month3 is          %result%
  2684.  
  2685. fdate /ff /odow#  /v
  2686. call Fergian dw- result %Fdate%
  2687. echo Day of week  is    %result%
  2688.  
  2689. fdate /ff /odow#  /v
  2690. call Fergian dw3 result %Fdate%
  2691. echo Day of week3 is    %result%
  2692.  
  2693. REM cleanup
  2694. set Fdate=
  2695. set result=
  2696.  
  2697. :55 Fergian.BAT (used in the previous example)
  2698. :==================================================================
  2699. @echo off
  2700. set  %2=
  2701. goto %1
  2702.  
  2703. goto end-doc
  2704. --------------------------------------------------------------------
  2705. This batch file converts a month number, or day of the week number,
  2706. to a name in the FERGIAN language.
  2707. You can copy this batch file and customize it, to make it translate
  2708. into some other language of your choice.
  2709.  
  2710. This batch file expects the following parameters:
  2711.  
  2712. %1 contains the type of number you want to convert:
  2713.    MM- if you want the entire name of the month
  2714.    MM3 if you want the first 3 letters of the name of the month
  2715.  
  2716.    DW- if you want the entire name of the day of the week
  2717.    DW3 if you want the first 3 letters of the name of the day of the week
  2718.  
  2719. %2 contains the name of the environment variable that you
  2720.    want to use to hold the result
  2721.  
  2722. %3 contains the number that you want to convert
  2723. --------------------------------------------------------------------
  2724. :end-doc
  2725.  
  2726. :MM-
  2727. if (%3)==(01) set %2=Jaded
  2728. if (%3)==(02) set %2=Febrile
  2729. if (%3)==(03) set %2=Martial
  2730. if (%3)==(04) set %2=Abigail
  2731. if (%3)==(05) set %2=Maybelene
  2732. if (%3)==(06) set %2=Junkaroo
  2733. if (%3)==(07) set %2=Julia
  2734. if (%3)==(08) set %2=Augmentation
  2735. if (%3)==(09) set %2=Separation
  2736. if (%3)==(10) set %2=Ostentation
  2737. if (%3)==(11) set %2=Novelty
  2738. if (%3)==(12) set %2=Decadence
  2739. goto endit
  2740.  
  2741. :
  2742. :MM3
  2743. if (%3)==(01) set %2=Jad
  2744. if (%3)==(02) set %2=Feb
  2745. if (%3)==(03) set %2=Mar
  2746. if (%3)==(04) set %2=Abi
  2747. if (%3)==(05) set %2=May
  2748. if (%3)==(06) set %2=Jun
  2749. if (%3)==(07) set %2=Jul
  2750. if (%3)==(08) set %2=Aug
  2751. if (%3)==(09) set %2=Sep
  2752. if (%3)==(10) set %2=Ost
  2753. if (%3)==(11) set %2=Nov
  2754. if (%3)==(12) set %2=Dec
  2755. goto endit
  2756.  
  2757. :DW-
  2758. if (%3)==(1) set %2=SunDay
  2759. if (%3)==(2) set %2=MoonDay
  2760. if (%3)==(3) set %2=TwickasDay
  2761. if (%3)==(4) set %2=WodensDay
  2762. if (%3)==(5) set %2=ThorsDay
  2763. if (%3)==(6) set %2=FreyasDay
  2764. if (%3)==(7) set %2=SaturnDay
  2765. goto endit
  2766.  
  2767.  
  2768. :DW3
  2769. if (%3)==(1) set %2=Sun
  2770. if (%3)==(2) set %2=Moo
  2771. if (%3)==(3) set %2=Twi
  2772. if (%3)==(4) set %2=Wod
  2773. if (%3)==(5) set %2=Tho
  2774. if (%3)==(6) set %2=Fre
  2775. if (%3)==(7) set %2=Sat
  2776. goto endit
  2777.  
  2778.  
  2779. :endit
  2780.  
  2781. :58 Convert numbers to "extended hex" (XX) format
  2782. :==================================================================
  2783. @echo off
  2784. cls
  2785. SET decnum=0
  2786. :top
  2787.    if (%decnum%)==(37) goto endit
  2788.    fdate /f#2xx /A%decnum% /P"XX representation of %decnum% is "
  2789.    fdate /f#add /A%decnum% /b1 /Vdecnum
  2790. goto top
  2791.  
  2792. :endit
  2793.  
  2794. :61 DO-ONCE: Run apps when booting for the first time of the day
  2795. :===============================================================
  2796. COMMENT
  2797.   Put this code in AUTOEXEC.BAT.  Note that this batch code requires DOS
  2798.   3.3+, since it uses CALL.
  2799.  
  2800. if not exist C:\LASTRUN.BAT goto RunNow
  2801.  
  2802. rem call LASTRUN.BAT, which will set an environment variable, %LASTRUN%,
  2803. rem that will contain the date when this batch file was last run.
  2804. rem ------------------------------------------------------------------
  2805. call C:\LASTRUN.BAT
  2806.  
  2807. rem compare the date in %LASTRUN% to today's date
  2808. rem ------------------------------------------------------------------
  2809. Fdate /Fcomp /At /B%LastRun% /Vcomp
  2810.  
  2811. : Today's date may be less than %LASTRUN% if you reset the system clock
  2812. IF (%COMP%)==(LT) goto NoRun
  2813. : If %LASTRUN% was the same as today's date,
  2814. :   then this batch file has already been run once today
  2815. IF (%COMP%)==(EQ) goto NoRun
  2816.  
  2817. : Daily processing hasn't been run today. Run it.
  2818. : Here, you should put the batch-file body --
  2819. : the code to run the applications that you want to run once per day
  2820. :
  2821.  
  2822. : ------------------------------------------------------------------
  2823. : Save today's date in a new version of LastRun.BAT.  Note that
  2824. : this code will be executed only if daily processing runs to
  2825. : completion without hanging the machine or aborting the batch file.
  2826. : ------------------------------------------------------------------
  2827. Fdate /Ff /Omm-dd-ccyy /At /P"@set LastRun=">LastRun.BAT
  2828.  
  2829. :NoRun
  2830. set LastRun=
  2831. set COMP=
  2832.  
  2833. :62 Run specific software, depending on the day of the week
  2834. :==================================================================
  2835. COMMENT
  2836. This is a very common use for Fdate.  I use it to load an alarm-clock TSR
  2837. (Terminate and Stay Resident, "memory resident", program) that beeps at me
  2838. (at different times on different days of the week) to remind me that it is
  2839. time to attend a meeting that is regularly scheduled for that day of the
  2840. week.
  2841.  
  2842. Note that stuff for a given day of the week will be executed every time you
  2843. boot up on that day of the week.  If you want stuff (e.g. a backup job) to
  2844. be run only once (the first time you boot up) on a given day of the week,
  2845. then:
  2846.  
  2847. (1)  copy the code from DO-ONCE (the previous example) into your
  2848.      AUTOEXEC.BAT file, then
  2849.  
  2850. (2)  copy this code into the body of the DO-ONCE code that you copied into
  2851.      AUTOEXEC.BAT in the last step.  If you do that, then this code will be
  2852.      run only once per day, even if you boot up multiple times per day.
  2853.  
  2854. Remember that if you are executing other batch files from a batch file, 
  2855. you should invoke them with a CALL statement:
  2856.               CALL batchfilename parm1 parm2 ...
  2857. so control will return to the calling batch file when execution of the
  2858. called batch file is complete.      
  2859.  
  2860. Note that the string comparison is case sensitive.
  2861. ==================================================================
  2862.  
  2863. :: get 3-character day-of-week name and put it in DOW e-var
  2864. FDATE /ff /oDOW3 /vDOW
  2865.  
  2866. if (%DOW%)==(Mon) alarmTSR.exe 10:30 Time for Monday staff meeting
  2867.  
  2868. if (%DOW%)==(Fri) echo Running Friday backup.  Please wait...
  2869. if (%DOW%)==(Fri) CALL BACKUP C: 
  2870. if (%DOW%)==(Fri) CALL BACKUP D: 
  2871. set dow=
  2872.  
  2873.  
  2874.  
  2875. :63 Run a program at a specified time later in the day
  2876. :==================================================================
  2877. COMMENT
  2878.   This batch file involves a lot of disk activity because DOS re-reads the
  2879.   batch file from disk every time it does a GOTO LOOPTOP.  You can avoid
  2880.   all this disk activity by running the batch file from a RAM DISK.
  2881.  
  2882. REM GET CURRENT ABSOLUTE MINUTE AND PUT IN ENVIRONMENT VARIABLE RUNTIME
  2883. FDATE /Ff /At /Ominute#  |STRINGS RunTime= ASK >NUL
  2884.  
  2885. REM ADD 120 MINUTES (2 HOURS) TO ENVIRONMENT VARIABLE RUNTIME
  2886. FDATE /F#add /A%RunTime% /B120 |STRINGS RunTime= ASK >NUL
  2887.  
  2888. REM LOOP UNTIL NOWTIME HAS REACHED RUNTIME
  2889. :LoopTop
  2890.   FDATE /Ff /At  /Ominute#   |STRINGS NowTime=  ASK >NUL
  2891.   FDATE /F#comp  /A%NowTime% /B%RunTime% |STRINGS TimeComp= ASK >NUL
  2892.   if (%TimeComp%)==(LT) goto loopTop
  2893. :LoopEnd
  2894.  
  2895. echo STARTING EXECUTION OF APPLICATION: [program name]
  2896.  
  2897.  
  2898.  
  2899. :66 Change a filename to contain today's date in first 3 bytes
  2900. :==================================================================
  2901. FDATE /Ff /Oxxx /vXXX
  2902. ren  BACKUP.LOG  %XXX%-BACK.LOG
  2903. SET  XXX=
  2904.  
  2905.  
  2906.  
  2907. :67 Change a file's name to a name that contains today's date
  2908. :==================================================================
  2909. FDATE /Ff /At /Oyymmdd /vdate1
  2910. ren  BACKUP.LOG  BK%DATE1%.LOG
  2911. SET  DATE1=
  2912.  
  2913.  
  2914.  
  2915. :68 Change a file's name to a name containing an absolute minute 
  2916. :===============================================================
  2917. COMMENT
  2918.   This is a way to keep a complete series of files, such as log files,
  2919.   that are all created with the same name on the same day.  The only
  2920.   requirement is that they be created at least one minute apart.  You
  2921.   won't need to be able to decipher the absolute minute to figure out when
  2922.   the file was created; you can simply do a DIR on the file and look at
  2923.   its date/time stamp.  
  2924.  
  2925. FDATE /FF /At /Ominute# /VJulMin
  2926. REN online.log %JulMin%.log
  2927. SET JulMin=
  2928.  
  2929.  
  2930. :71 Extract the rightmost n characters of a string 
  2931. :===============================================================
  2932. rem extract the rightmost 6 characters of a string
  2933. FDATE /Fsubstr /a-6     /Q"1994 Jun 03"   ===> "Jun 03"     
  2934.  
  2935. HOW FDATE THINKS ABOUT DATES
  2936. ============================
  2937.  
  2938. FDATE'S BUSINESS VIEW OF THE CALENDAR
  2939. =====================================
  2940.  
  2941.   FDATE is intended for business applications, not historical ones.  
  2942.  
  2943.   FDATE does not take into account historical changes in the calendar such
  2944.   as the ten days that were dropped from the British calendar when Britain
  2945.   moved from the Julian to the Gregorian calendar in the 18th century, or
  2946.   the 11 days that were dropped from the Russian calendar when Russia made
  2947.   the same move in the early 20th century.
  2948.  
  2949.   As far as FDATE is concerned, the calendar has followed the same
  2950.   pattern, unchanged, since January 1, 0001.
  2951.  
  2952.  
  2953. FDATE'S BASE DATE
  2954. =================
  2955.   Internally, Fdate's date manipulations are based on translating a
  2956.   calendar date into an "absolute" or "TRUE Julian" date:  a date
  2957.   expressed as the number of days from some day in the distant past.
  2958.  
  2959.   FDATE's base date is January 1, 0001 (i.e. day 1 of month 1 of year 1)
  2960.   FDATE's absolute date for January 1, 0001 is      1.
  2961.   FDATE's absolute date for January 1, 1992 is 727198.
  2962.  
  2963.  
  2964. FDATE'S LEAP YEAR ALGORITHM
  2965. ===========================
  2966.     Every year evenly divisible by 4 IS a leap year
  2967.       EXCEPT THAT
  2968.         Every year evenly divisible by 100 IS NOT a leap year
  2969.           EXCEPT THAT
  2970.             Every year evenly divisible by 400 IS a leap year
  2971.     .
  2972.     Using this algorithm
  2973.          1983  is not a leap year
  2974.          1984  is     a leap year
  2975.          1900  is not a leap year
  2976.          2000  is     a leap year
  2977.  
  2978.     See "A Machine Algorithm for Processing Calendar Dates", by
  2979.          Henry F. Fliegel (Georgetown University Observatory) and
  2980.          Thomas C. Van Flandern (U.S. Naval Observatory)
  2981.          COMMUNICATIONS OF THE ACM, Volume 11, Number 10, October 1968
  2982.  
  2983. There is supposedly a new adjustment to the leapyear algorithm,
  2984. which specifies the additional exception:
  2985.  
  2986.               EXCEPT THAT
  2987.                 Every year evenly divisible by 4000 IS a leap year
  2988.  
  2989. See "Bit By Bit" column, COMPUTER LANGUAGE, November 1989, p. 148.
  2990. This adjustment is not part of FDATE's leapyear algorithm.
  2991. Unless your application is working with dates 2,000 years in the
  2992. future, the lack of this exception will be irrelevant for you.
  2993.  
  2994. FDATE'S CENTURY-ASSUMPTION ALGORITHM
  2995. ====================================
  2996. If an input date is supplied in a format in which the year is
  2997. specified without a century -- that is, as YY rather than CCYY --
  2998. then Fdate does not automatically use the current century.
  2999. Instead,
  3000.  
  3001.    *  if YY is greater than 20,       then FDATE assumes CC = 19
  3002.    *  if YY is less than or equal 20, then FDATE assumes CC = 20
  3003.  
  3004. Examples:
  3005.          21    becomes  1921
  3006.          ...
  3007.          99    becomes  1999
  3008.          00    becomes  2000
  3009.          01    becomes  2001
  3010.          ...
  3011.          20    becomes  2020
  3012. but then (again)
  3013.          21    becomes  1921
  3014.  
  3015. To put it simply, FDATE makes what would be a reasonable assumption
  3016. about the century for someone operating in the 1990's: it looks back to
  3017. 1921 and forward to 2020.  If both I and FDATE are still alive in the
  3018. year 2000, I'll probably update FDATE's century-assumption algorithm to
  3019. shift it forward several decades.
  3020.  
  3021.  
  3022. FDATE'S IMPLEMENTATION LIMITS
  3023. ====================================
  3024. Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
  3025. which means that Fdate can accept numbers up to 9 digits long.
  3026.  
  3027. DISTRIBUTION ISSUES
  3028. ===================
  3029.  
  3030. USE, REGISTRATION, AND DISTRIBUTION OF FDATE
  3031. ============================================
  3032.  
  3033. FDATE is freeware, or what is known as "zero-cost shareware".  FDATE is not
  3034. what is technically called "public domain" software because the author
  3035. retains the copyright.  FDATE can, however, be copied, used, and
  3036. distributed freely as long as FDATE.EXE and its associated doc file
  3037. (FDATE.DOC) and demonstration batch files and doc files (HOLIDAYS.BAT,
  3038. HOLIFEDS.BAT, HOLIFEDS.DOC) are not altered and are distributed together.  
  3039.  
  3040. There is no requirement to register FDATE in any way.
  3041.  
  3042. FDATE can be included in shareware packages as long as both FDATE and
  3043. its related files are included in the shareware package.
  3044.  
  3045. If you have received FDATE as part of some larger shareware package,
  3046. please be aware that you may freely use, copy, and distribute FDATE
  3047. without paying a fee for, or registering, the larger package.
  3048.  
  3049. The author explicitly disavows any claim whatsoever about the
  3050. correctness or functionality of FDATE, its documentation, and its
  3051. demonstration batch files, and disclaims liability for anything and
  3052. everything bad that might happen in connection with, before, during, or
  3053. after using it.  I have tried to make FDATE work right, but everybody
  3054. makes mistakes, so you use FDATE at your own risk.
  3055.  
  3056. I don't know if people will find FDATE useful, and I'd like to find
  3057. out.  If you find FDATE useful and use it on a regular basis, I'd
  3058. appreciate it if you would drop me a short note via US mail or
  3059. CompuServe, telling me about how you are using FDATE.
  3060.  
  3061. If you need other input/output formats, please contact the author.
  3062.  
  3063.  
  3064. TECHNICAL SUPPORT FOR FDATE
  3065. ===============================================
  3066.  
  3067. Send me a message via CompuServe mail; I'll respond.  When sending your
  3068. message, please let me know what version of Fdate you're using.
  3069.  
  3070.  
  3071. WHERE TO FIND THE MOST CURRENT VERSION OF FDATE
  3072. ===============================================
  3073.  
  3074. You will always be able to find the most recent version of FDATE on
  3075. CompuServe.  The filename will be FDATE.ZIP, and it will be available in
  3076. the CIS:IBMSYS forum (library 1, the "DOS Utilities" library).
  3077.  
  3078. If you have problems finding it, try using cross-library searching, looking
  3079. for the filename FDATE.ZIP or the keyword FDATE.
  3080.  
  3081.  
  3082. UPLOADING FDATE TO ELECTRONIC BULLETIN BOARDS
  3083. ===============================================
  3084.  
  3085. Feel free to post copies of FDATE.ZIP on any BBS that you wish, but please
  3086. do not upload it to any CompuServe library.  As long as I am the only one
  3087. putting copies of FDATE onto CompuServe, we can keep confusion over
  3088. versions to a minimum.
  3089.  
  3090. I distribute all versions of FDATE in a files called FDATE.ZIP, rather than
  3091. embedding information about the version in the file name.  I think doing
  3092. this helps newer versions of FDATE to force older versions out of
  3093. circulation.  To give a BBS user information about the version, I always
  3094. identify the version of FDATE in the 1-line file description that most BBSs
  3095. support.  
  3096.  
  3097.  
  3098. CONTENTS OF THE FDATE.ZIP DISTRIBUTION FILE
  3099. ===========================================
  3100.  
  3101. The current distribution package (FDATE.ZIP) contains the following:
  3102.  
  3103.        FDATE.EXE         [the FDATE program]
  3104.        FDATE.DOC         [this file, documentation for FDATE]
  3105.  
  3106.   [demonstration batch files]
  3107.        HOLIDAYS.BAT
  3108.        HOLIFEDS.BAT and HOLIFEDS.DOC
  3109.  
  3110. RECENT FDATE REVISION HISTORY
  3111. =============================
  3112.  
  3113. Letters appended to version numbers indicate modifications to
  3114. the doc files, without any modification to the FDATE.EXE software.
  3115. Asterisks (*) indicate most important changes in the new version.
  3116.  
  3117. 7.0a   Nov 14, 1992
  3118.        Added #mod function
  3119.        Major reformatting of documentation to make it more user-friendly
  3120.    
  3121. 7.1a   Apr 15, 1993
  3122.        Added German language support.  Thanks for the request, and the
  3123.        necessary information, from Patrick Schmucki, via the Active-Net
  3124.        BBS in Rapperswil, Switzerland.
  3125.  
  3126. 8.0    July, 1993
  3127.        Added "V" (validate) and "m" (month addition/subtraction) functions
  3128.        Added math functions: #mult #div #idiv
  3129.        Added /T (time) parameter
  3130.  
  3131.        Added FORATIME.BAT example, which Walter Ledge (assistant sysop of
  3132.        CompuServe's CRFORUM) and I developed.  A big thanks to Walt for
  3133.        his feedback and help.
  3134.  
  3135. 8.1    July 27, 1993  BUG FIX
  3136.        An error-trapping routine that was added to version 7.9 contained a
  3137.        bug that caused Fdate's numeric math functions (#add, #dif, #mult,
  3138.        #div, #idiv, #mod, #comp, etc.) to return incorrect results. 
  3139.        
  3140. 8.2    August, 1993
  3141.        Removed FILEDATE.BAT from the distribution .ZIP file.
  3142.  
  3143.        Corrected the Spanish and French "full" and "d1" output formats. 
  3144.        Thanks for the information on Spanish and French date formats to
  3145.        Gene J. Raymond, of GJR Software Products.
  3146.  
  3147. 8.3a   Feb 24, 1994
  3148.  
  3149. *      Added the following string-handling functions:
  3150.        get    (get user input)
  3151.        getu   (get uppercase user input)
  3152.        upper  (uppercase a string)
  3153.        len    (length of a string)
  3154.        substr (substring)
  3155.  
  3156. *      Added /F#2xx (convert number to extended hex format) function. 
  3157.        Deleted SETXX.BAT, which has been made obsolete with the addition
  3158.        of this new function.  Modified second example of storing a 4-digit
  3159.        date to use #2xx instead of SETXX.BAT.
  3160.  
  3161. *      Added output formats "ddmmccyy" and "ddmmyy" at the request of
  3162.        several users.
  3163.  
  3164. *      Added output format "xxx" after several requests for advice on how
  3165.        to represent a large range of dates in a minimum number of bytes
  3166.        (usually for constructing filenames from today's date).
  3167.  
  3168. *      At the request of several users, enhanced the "compare" functions
  3169.        (comp, tcomp, #comp) so they set distinctive errorlevels for their
  3170.        different results.  See the table of contents ("COMPARE-FUNCTION
  3171.        ERRORLEVELS") and EXAMPLES.
  3172.  
  3173.        To discussion of /Fv parameter, added note about almost always
  3174.        redirecting output to NUL when using /Fv.
  3175.  
  3176.        Revised FORATIME.BAT example batch file to make error-correction a
  3177.        bit more robust and to add better documentation on how to use it.
  3178.  
  3179.        Added example batch files to use new functions, especially
  3180.        FORATIM2.BAT which uses new "get" function
  3181.  
  3182.        Removed FDATEX.BAT demonstration batch file from distribution
  3183.        package, to reduce its size.  The examples in this DOC file should
  3184.        make the examples in FDATEX.BAT unnecessary
  3185.  
  3186.  
  3187. 8.4a   March 20, 1994
  3188. *      Added GETK (get keypress) function
  3189.  
  3190. *      Added ability to use /V when running in a Windows DOS box, thanks
  3191.        to a Turbo Pascal routine from the Turbo Professional library
  3192.        provided by Kim Kokkonen of TurboPower Software.
  3193.  
  3194.        Fixed a bug in which the prompt string (/Q) for the GET and GETU
  3195.        functions was being written to redirectable output (StdOut).  The
  3196.        prompt string is now written directly to the screen, and will not
  3197.        appear in FDATE's output when the output is redirected to a file.
  3198.  
  3199.        Removed ALARM.BAT, ALARM.DOC, TIC.BAT and TIC.DOC from distribution
  3200.        package.  They were too esoteric to be generally helpful.
  3201.  
  3202.        Added FILE_ID.DIZ and DESC.SDI to distribution package.
  3203.  
  3204.        Corrected algorithm for Mardi Gras in HOLIDAYS.BAT.  Modified
  3205.        HOLIDAYS.BAT and HOLIFEDS.BAT to make them more interactive, using
  3206.        FDATE's new abilities to get user input.
  3207.  
  3208. *      Started ZIPing FDATE.ZIP with PKZIP 2.04g rather than version 1.1
  3209.